我面临一个问题。我在代码隐藏中使用TreeViewItem的不同阶段创建了TreeView。我添加了一个带有功能“添加项目”的ContextMenu。当我调用此函数时,我将创建一个新项并将其添加到TreeView中。 问题在于视图永远不会改变。 我确定新项目属于TreeViewItem的列表(我在调试时看过)。 我试过了:
adjustedMap
还有:
tree.Items.Refresh
有我的代码:
this.UpdateLayout();
当我单击“验证”按钮时,它将启动此功能:
public void FillTree(TreeView tree, ObservableCollection<MyObject> nodes)
{
tree.Items.Clear();
TreeViewItem Items= new TreeViewItem();
Items.Header = "Items";
TreeViewItem Item1;
TreeViewItem Item2;
for (int i = 0; i < nodes.Count; i++)
{
Item1 = new TreeViewItem();
Item1.Header = nodes[i].Name;
if(nodes[i].list != null && nodes[i].list.Count>0)
{
for(int j = 0; j < nodes[i].list.Count; j++)
{
Item2 = new TreeViewItem();
Item2.Header = nodes[i].list[j].Name;
Item1.Items.Add(Item2);
}
}
Items.Items.Add(Items1);
}
tree.Items.Add(Items);
}
如果有人有刷新视图的想法,对我会有很大帮助
先谢谢您
答案 0 :(得分:0)
要将以上内容移到允许正确绑定数据的结构中,您需要在DataContext类中添加以下属性:
public ObservableCollection<TreeViewItemContext> Collection { get => this._Collection; set { this._Collection = value; this.RaisePropertyChanged(); } }
private ObservableCollection<TreeViewItemContext> _Collection;
TreeViewItemContext
类必须看起来像这样才能迭代所有项目:
public class TreeViewItemContext
{
public ObservableCollection<TreeViewItemContext> Children { get; }
public MyObject Wrapped { get; }
/* Other properties etc. go in here. */
public TreeViewItemContext(MyObject wrapped)
{
this.Children = new ObservableCollection<TreeViewItemContext>();
this.Wrapped = wrapped;
}
public IEnumerable<TreeViewItemContext> IterateTree()
{
yield return this;
foreach (var tvic in this.Children)
{
foreach (var it in tvic.IterateTree())
{
yield return it;
}
}
}
}
您的XAML代码将像这样简单:
<TreeView ItemsSource="{Binding Collection}">
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}>
<Setter Property="Header" Value="{Binding Wrapped.Name}"/>
</Style>
</TreeView.ItemContainerStyle>
<TreeView.Resources>
<HierarchialDataTemplate ItemsSource="{Binding Children}">
<!-- Your DataTemplate-Content Goes In Here -->
</HierarchialDataTemplate>
</TreeView.Resources>
</TreeView>
然后要遍历TreeView中的所有项目,只需在主DataContext对象中执行Collection.SelectMany((it) => it.IterateTree())
并对其进行处理即可。
然后执行此操作还可以使您通过向集合中添加/删除项目或仅创建一个新集合来“仅”更新集合。
RaisePropertyChanged
方法顺便说一句。总是差不多:
public class AnyClass : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged([System.Runtime.CompilerServices.CallerMemberName]string callee = "") => this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(callee));
//...
}
您所有的“更新”问题都将消失。
答案 1 :(得分:0)
使用WPF的模板功能可以轻松解决此问题,而不必尝试构建整个UI。在代码中。
您已经有一个可观察的项目集合,因此只需将TreeView的ItemsSource设置为该项目即可。在树中,使用HierachicalDataTemplate指定每个项目的显示方式。
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type MyObject}"
ItemsSource="{Binding list}">
<TextBlock Text="{Binding Name}" />
</HierarchicalDataTemplate>
</TreeView.Resources>
请注意,列表和名称必须是MyObject类的公共属性(而不是字段)。
这样,您可以根据需要具有任意数量的嵌套项目,而不仅限于代码将支持的两个子级别。
如果list也是一个可观察的集合,并且Name(以及您要显示的任何其他属性)实现了INotifyPropertyChanged模式,则在对MyObject项进行任何更改之后,TreeView显示将自动更新,而无需进一步的处理。 / p>
如果您想全力以赴并完全实现MVVM设计模式,那么可以在我的blog post上找到介绍。