WPF TreeView-添加/删除节点后如何刷新树?
我参考这篇文章:
WPF TreeView HierarchicalDataTemplate - 绑定到具有多个子集合的对象
并修改树结构,例如:
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);
}
当我单击特定节点“Entry”上的右键以添加新节点时条目下的节点“源” (调用“Add”方法),我在 Entry 下成功添加了一个新的“Source”对象,但我在树视图上看不到这个新节点。添加/删除节点时如何刷新树视图?
I refer to this article:
WPF TreeView HierarchicalDataTemplate - binding to object with multiple child collections
and modify the tree structure like:
Root
|__Group
|_Entry
|_Source
In 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;
}
}
}
In Source.cs:
public class Source
{
public int Key { get; set; }
public string Name { get; set; }
}
In XAML file:
<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>
In 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);
}
When I click right button on specific node "Entry" to add a new node "Source" under Entry
(call "Add" method), I add a new "Source" object under Entry successfully, but I can't see this new node on treeview. How to refresh treeview when adding/deleting node?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果您想通知用户界面某些情况,请使用 ObservableCollection 而不是 IList集合中的内容已更改
Use ObservableCollection instead of IList if you want to notify the user interface that something in the collection has changed
就我而言,将
Items
的类型更改为ObservableCollection
无法解决问题。您需要实现INotifyPropertyChanged
。我测试了树视图的两种解决方案,因为我遇到了同样的问题。
就我而言,将类型从 IList 更改为 ObservableCollection 并没有刷新 GUI。但是,当我将 auto 属性更改为:
即
,我已经实现了 INotifyPropertyChanged ,这改变了情况。构建树结构的方法将
Items
的实际类型定义为 newList()
,但它可以工作并刷新 GUI 。尽管如此,我的树是用纯 MVVM 模式构建的,没有使用代码隐藏。
使用
我在我使用的视图模型中
和 :这意味着我没有添加/删除项目,但我重建了 Node 的子集合。
As far as I'm concerned, changing of type for
Items
toObservableCollection<T>
will not resolve the problem. You need to implementINotifyPropertyChanged
.I tested both solutions for my tree view, because I faced the same problem.
In my case changing of type from IList to ObservableCollection didn't refreshed GUI. However when I changed my auto property:
to
Namely, I've implemented
INotifyPropertyChanged
and that changed the situation. The method that builds the tree structure defines the actual type ofItems
as newList<T>()
, but it works and refreshes the GUI .Nevertheless my tree was built in pure MVVM pattern without usage code-behind.
I use
and in the view model I use:
That means I didn't added/removed items, but I rebuilt Node's sub collection.
使用此类,Sources 集合中的任何更改都将更新/刷新 UI 中的树。
Use this class and any changes in Sources collection will update/refresh tree in UI.