2012-04-25 4 views
0

나는 다음과 같은 요구 사항이 있습니다 TreeView 항목 선택한 항목의 데이터의 변화는 부모 창에 잘못 반영

  • 세부 정보 표시를의

    1. 표시 TreeView합니다.
    2. 선택한 항목을 편집하는 대화 상자입니다.

    이러한 요구 사항을 구현했지만 세 번째는 수행해야 할 작업을 수행하지 않아 막혔습니다.

    원하는 작업 : 편집 대화 상자에서 항목을 편집 할 수 있어야합니다. 이것은 TreeViewItem 아니지만 내 수업 중 하나의 인스턴스입니다.

    1. 편집 내용 저장 - 대화 상자를 닫을 버튼.
    2. 편집 내용 삭제 - 항목 및 닫는 대화 상자에서 변경된 필드를 재설정하는 버튼입니다.

    두 번째 요구 사항이 작동하지 않습니다. 필드를 편집하고 취소를 누르면 품목 세부 정보 패널에 편집 내용이 계속 표시됩니다. 디버깅했지만 기본 항목이 변경되지 않았 음을 알 수 있습니다. 그러나 항목이 변경된 값으로 표시됩니다.

    코드 :

    1. Item 클래스 (카테고리)

      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. 항목 편집기 창 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. 항목 편집기 창 코드 : 나는 CategoryDefineWindow.Cancelled 방법을 디버깅했습니다과 _category 객체가 제대로 재설정

      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(); 
          } 
      } 
      

    . 나는 그것이 잘못되어가는 것을 발견 할 수 없다.

  • +1

    세부 정보 패널은 처음에 업데이트 된 값을 어떻게 받습니까? Category 클래스가 INotifyPropertyChanged를 구현합니까? – Jefim

    +0

    그냥 참고 사항 : 인터페이스 ICloneable 구현하는 것이 좋습니다 및 해당 복제 메서드에서 메서드를 사용하여 object.MemberwiseClone(). 이렇게하면 복사하는 속성의 수가 증가 할 때 구현하기가 번거롭고 모든 속성 복사 항목이 필요하지 않습니다. – SvenG

    +0

    @Jefim : 'TreeView.SelectedItem'을 상표.'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; 
    }