2011-02-10 3 views
3

я обратиться к этой статье:WPF TreeView. Как обновить дерево после добавления/удаления узла?

WPF TreeView HierarchicalDataTemplate - binding to object with multiple child collections

и изменить структуру дерева, как:

Root 
    |__Group 
     |_Entry 
      |_Source 

В Entry.cs:

public class Entry 
{ 
    public int Key { get; set; } 
    public string Name { get; set; } 

    public ObservableCollection<Source> Sources { get; set; } 

    public Entry() 
    { 
     Sources = new ObservableCollection<Source>(); 
    } 

    public ObservableCollection<object> Items 
    { 
     get 
     { 
      ObservableCollection<object> childNodes = new ObservableCollection<object>(); 

      foreach (var source in this.Sources) 
       childNodes.Add(source); 

      return childNodes; 
     } 
    } 
} 

В Source.cs:

public class Source 
{ 
    public int Key { get; set; } 
    public string Name { get; set; } 
} 

В XAML файл:

<UserControl.CommandBindings> 
    <CommandBinding Command="New" Executed="Add" /> 
</UserControl.CommandBindings> 

    <TreeView x:Name="TreeView"> 
     <TreeView.ItemContainerStyle> 
      <Style TargetType="{x:Type TreeViewItem}"> 
       <Setter Property="TreeViewItem.IsExpanded" Value="True"/> 
      </Style> 
     </TreeView.ItemContainerStyle> 

     <TreeView.Resources> 
      <HierarchicalDataTemplate DataType="{x:Type local:Root}" ItemsSource="{Binding Items}"> 
       <TextBlock Text="{Binding Path=Name}" IsEnabled="True"> 
       </TextBlock> 
      </HierarchicalDataTemplate> 

      <HierarchicalDataTemplate DataType="{x:Type local:Group}" ItemsSource="{Binding Items}"> 
       <TextBlock Text="{Binding Path=Name}" IsEnabled="True"> 
       </TextBlock> 
      </HierarchicalDataTemplate> 


      <HierarchicalDataTemplate DataType="{x:Type local:Entry}" ItemsSource="{Binding Items}"> 
       <StackPanel Orientation="Horizontal"> 
        <TextBlock Text="{Binding Path=Name}" IsEnabled="True"> 
         <TextBlock.ContextMenu> 
          <ContextMenu > 
           <MenuItem Header="Add" Command="New"> 
           </MenuItem> 
          </ContextMenu> 
         </TextBlock.ContextMenu> 
        </TextBlock> 
       </StackPanel> 
      </HierarchicalDataTemplate> 


      <DataTemplate DataType="{x:Type local:Source}" > 
       <TextBlock Text="{Binding Path=Name}" /> 
      </DataTemplate> 

     </TreeView.Resources> 
    </TreeView> 

В UserControl.cs:

public ObservableCollection<Root> Roots = new ObservableCollection<Root>(); 

    public UserControl6() 
    { 
     InitializeComponent(); 

     //...Add new node manually 

     TreeView.ItemsSource = Roots; 
    } 

    private void Add(object sender, ExecutedRoutedEventArgs e) 
    { 
     Entry ee = (Entry)TreeView.SelectedItem; 
     Source s3 = new Source() { Key = 3, Name = "New Source" }; 
     ee.Sources.Add(s3); 
    } 

При нажатии правой кнопки мыши на определенном узел "Ввод", чтобы добавить новый узел "Source" под записью (вызов «Добавить»), я добавляю новый объект «Источник» в разделе «Запись» успешно, но я не вижу этот новый узел в дереве. Как обновить treeview при добавлении/удалении узла?

ответ

6

Использование ObservableCollection вместо IList, если вы хотите, чтобы уведомить пользовательский интерфейс, который что-то в коллекции изменилась

+0

Хорошо! Я изменяю все IList и List на «ObservableCollection». Затем, как я могу уведомить пользовательский интерфейс, что-то в коллекции изменилось? (Извините, я новичок в WPF) – user610801

+0

@ user610801, просто изменить тип коллекции на ObservableCollection было достаточно, чтобы обновить WPF TreeView, когда я добавляю/удаляю элементы из коллекционирования. – jcelgin

0

Насколько я понимаю, изменение типа для Items в ObservableCollection<T> не решит проблему. Вам необходимо реализовать INotifyPropertyChanged. Я проверил оба решения для моего древовидного вида, потому что я столкнулся с той же проблемой. В моем случае изменение типа от IList до ObservableCollection не обновило GUI. Однако, когда я изменил свое авто свойство:

public List<SourceControlItemViewBaseModel> Items { get; set; } 

в

private IEnumerable<SourceControlItemViewBaseModel> _items; 
    public IEnumerable<SourceControlItemViewBaseModel> Items 
    { 
     get { return _items; } 
     set 
     { 
      _items = value; 
      OnPropertyChanged(); 
     } 
    } 

А именно, я реализовал INotifyPropertyChanged и что изменило ситуацию. Метод, который строит древовидную структуру, определяет фактический тип Items как новый List<T>(), но он работает и обновляет GUI. Тем не менее, мое дерево было построено в чистом шаблоне MVVM без использования кода. Я использую

<TreeView ItemsSource="{Binding SourceControlStructureItems}" /> 

и в модели представления я использую:

currentVm.Items= await SourceControlRepository.Instance.BuildSourceControlStructureAsync(currentVm.ServerPath); 

Это означает, что я не добавлять/удалять элементы, но перестроен к югу коллекции узла.