2012-04-25 4 views
0

У меня есть следующие требования:изменения данных отражается неправильно в родительском окне

  1. Показать TreeView пунктов
  2. Показать подробную информацию о выбранном элементе в TreeView.
  3. Диалог для редактирования выбранного элемента.

Я выполнил эти требования, но третий не делает то, что он должен делать, я застрял.

Что я хочу: Диалог редактирования должен иметь возможность редактировать элемент. Это не TreeViewItem, а экземпляр одного из моих классов.

  1. Сохраните изменения - кнопка, которая только что закроет диалог.
  2. Отменить изменения - кнопка для сброса полей, измененных в элементе, и закрытия диалогового окна.

Второе требование не работает. Если я отредактирую поле и нажмите «Отмена», на панели сведений о деталях будут отображаться изменения. Я отлаживал, но обнаружил, что базовый элемент не изменился - однако элемент отображается с измененными значениями.

Код:

  1. товара класс (категория)

    public class Category 
    { 
        public virtual int Id { get; set; } 
        public virtual string Name { get; set; } 
        public virtual string Description { get; set; } 
        public virtual Unit Unit { get; set; } 
        public virtual List<Category> ChildCategories { get; set; } 
        public virtual Category ParentCategory { get; set; } 
        public virtual bool IsMainCategory { get; set; } 
    
        public Category() 
        { 
         ChildCategories = new List<Category>(); 
        } 
    
        public virtual void AddChild(Category child) 
        { 
         ChildCategories.Add(child); 
         child.ParentCategory = this; 
        } 
    } 
    
  2. товара (Категория) Подробности приведены в этикетке:

    <DataTemplate DataType="{x:Type local:Category}"> 
        <Grid> 
         <Grid.ColumnDefinitions> 
          <ColumnDefinition Width="4*" SharedSizeGroup="a" /> 
          <ColumnDefinition Width="6*" SharedSizeGroup="b" /> 
         </Grid.ColumnDefinitions> 
         <Grid.RowDefinitions> 
          <RowDefinition Height="1*" /> 
          <RowDefinition Height="1*" /> 
         </Grid.RowDefinitions> 
    
         <TextBlock Text="Name" Grid.Column="0" Grid.Row="0" Padding="5"/> 
         <TextBlock Text="{Binding Path=Name}" Grid.Column="1" Grid.Row="0" Padding="5"/> 
         <TextBlock Text="Description" Grid.Column="0" Grid.Row="1" Padding="5"/> 
         <TextBlock Text="{Binding Path=Description}" Grid.Column="1" Grid.Row="1" Padding="5"/> 
        </Grid> 
    </DataTemplate> 
    
  3. обработчик событий для редактирования элемента в главном окне:

    private void EditCategory(object sender, RoutedEventArgs e) 
    { 
        Category ctg = _tree.SelectedItem as Category; 
        if (ctg != null) 
        { 
         CategoryDefineWindow cdw = new CategoryDefineWindow(); 
         cdw.CategoryObject = ctg; 
         cdw.ShowDialog(); 
        } 
    } 
    
  4. Item окно редактора XAML:

    <Window x:Class="BSRCat.View.CategoryDefineWindow" 
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        Height="150" Width="500"> 
    <Grid> 
        <Grid.ColumnDefinitions> 
         <ColumnDefinition Width="3*" SharedSizeGroup="a" /> 
         <ColumnDefinition Width="7*" SharedSizeGroup="b" /> 
        </Grid.ColumnDefinitions> 
        <Grid.RowDefinitions> 
         <RowDefinition Height="1*" /> 
         <RowDefinition Height="1*" /> 
         <RowDefinition Height="1*" /> 
        </Grid.RowDefinitions> 
    
        <TextBlock Text="Name" Grid.Column="0" Grid.Row="0" Padding="5"/> 
        <TextBox Text="{Binding Path=CategoryObject.Name, RelativeSource={RelativeSource AncestorType=Window}}" Grid.Column="1" Grid.Row="0" Padding="5"/> 
        <TextBlock Text="Description" Grid.Column="0" Grid.Row="1" Padding="5"/> 
        <TextBox Text="{Binding Path=CategoryObject.Description, RelativeSource={RelativeSource AncestorType=Window}}" Grid.Column="1" Grid.Row="1" Padding="5"/> 
    
        <StackPanel Orientation="Horizontal" Grid.Row="2" Grid.ColumnSpan="2" HorizontalAlignment="Right"> 
         <Button Content="Ok" Margin="5" Height="20" Width="30" Click="Confirmed"/> 
         <Button Content="Cancel" Margin="5" Height="20" Width="50" Click="Cancelled"/> 
        </StackPanel> 
    </Grid> 
    </Window> 
    
  5. Код продукта Окно редактора за:

    public partial class CategoryDefineWindow : Window 
    { 
        public Category CategoryObject 
        { 
         get 
         { 
         return _category; 
         } 
         set 
         { 
          _category = value; 
          _initial = new Category() { Name = value.Name, Description = value.Description  }; 
         } 
        } 
    
        private Category _category; 
        private Category _initial; 
    
        public CategoryDefineWindow() 
        { 
         InitializeComponent(); 
        } 
    
        private void Confirmed(object sender, RoutedEventArgs e) 
        { 
         Close(); 
        } 
    
        private void Cancelled(object sender, RoutedEventArgs e) 
        { 
         _category.Name = _initial.Name; 
         _category.Description = _initial.Description; 
         Close(); 
        } 
    } 
    

Я отлажена метод CategoryDefineWindow.Cancelled и объект _category правильно сбросить. Я не могу найти, где это происходит.

+1

Как панель сведений получает обновленные значения в первую очередь? Использует ли класс класса INotifyPropertyChanged? – Jefim

+0

Просто примечание: я бы рекомендовал реализовать интерфейс ICloneable и в своем методе клонирования использовать метод object.MemberwiseClone(). Таким образом вам не нужен весь этот атрибут, копирующий материал, который является громоздким для реализации, когда число атрибутов, которое вам нужно копировать, увеличивается. – SvenG

+0

@Jefim: я привязал свойство TreeView.SelectedItem к свойству Content. метка.С определением 'DataTemplate' я получаю панель сведений таким образом. – nakiya

ответ

1

Класс категории должен быть реализован с помощью интерфейса INotifyPropertyChanged. WPF будет уведомлен после изменения стоимости свойств.

public class Category : INotifyPropertyChanged 
{ 
    private string _Name; 
    private string _Description; 

    public virtual int Id { get; set; } 
    public virtual string Name 
    { 
     get 
     { 
      return _Name; 
     } 
     set 
     { 
      if (_Name == value) 
       return; 

      _Name = value; 
      NotifyPropertyChanged("Name"); 
     } 
    } 

    public virtual string Description 
    { 
     get 
     { 
      return _Description; 
     } 
     set 
     { 
      if (_Description == value) 
       return; 

      _Description = value; 
      NotifyPropertyChanged("Description"); 
     } 
    } 
    public virtual Unit Unit { get; set; } 
    public virtual List<Category> ChildCategories { get; set; } 
    public virtual Category ParentCategory { get; set; } 
    public virtual bool IsMainCategory { get; set; } 

    public Category() 
    { 
     ChildCategories = new List<Category>(); 
    } 

    public virtual void AddChild(Category child) 
    { 
     ChildCategories.Add(child); 
     child.ParentCategory = this; 
    } 

    private void NotifyPropertyChanged(string propertyName) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
} 
Смежные вопросы