【问题标题】:WPF TreeView-How to refresh tree after adding/removing node?WPF TreeView-添加/删除节点后如何刷新树?
【发布时间】:2011-02-10 05:17:26
【问题描述】:

我参考这篇文章:

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

当我单击特定节点“条目”上的右键以在条目下添加一个新节点“源”时 (调用“Add”方法),我成功在Entry下添加了一个新的“Source”对象,但是在treeview上看不到这个新节点。添加/删除节点时如何刷新treeview?

【问题讨论】:

    标签: c# wpf xaml treeview hierarchicaldatatemplate


    【解决方案1】:

    如果您想通知用户界面集合中的某些内容已更改,请使用 ObservableCollection 而不是 IList

    【讨论】:

    • 好的!我将所有 IList 和 List 更改为“ObservableCollection”。接下来,如何通知用户界面集合中的某些内容发生了变化? (抱歉,我是 WPF 新手)
    • @user610801,只需将集合类型更改为 ObservableCollection 就足以在我从集合中添加/删除项目时更新我的​​ WPF TreeView。
    【解决方案2】:

    就我而言,将Items 的类型更改为ObservableCollection&lt;T&gt; 不会解决问题。你需要实现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 的实际类型定义为 new List&lt;T&gt;(),但它可以工作并刷新 GUI。 尽管如此,我的树是用纯 MVVM 模式构建的,没有使用代码隐藏。 我用

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

    在我使用的视图模型中:

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

    这意味着我没有添加/删除项目,而是重建了 Node 的子集合。

    【讨论】:

      【解决方案3】:

      使用此类,Sources 集合中的任何更改都将更新/刷新 UI 中的树。

      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 CompositeCollection Items
          {
             get
             {
                return new CompositeCollection()
                {
                   new CollectionContainer() { Collection = Sources },
                   // Add other type of collection in composite collection
                   // new CollectionContainer() { Collection = OtherTypeSources }
                };
             } 
          }
      
       }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-12-31
        • 1970-01-01
        • 1970-01-01
        • 2011-04-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多