Treeview
分别有两个数据模板HierarchicalDataTemplate
(层级数据模板)和DataTemplate
(数据模板),分别应用于生成子数据项和普通数据项。
在使用过程中,如果对两个模板的DataType
设置为同一类型,运行时会直接报错。
大概原因是添加了俩个相同Key的资源(因为HierarchicalDataTemplate
和DataTemplate
都是定义在
标签中)。
代码:
public class TypeTreeModel :TypeModel
{
public ObservableCollection ChildList { get; set; }
= new ObservableCollection();
}
public class TypeModel
{
public int Id { get; set; }
public string Name { get; set; }
}
TypeList
一般都是数据库取出来的数据处理嵌套后的结果。有时候会遇到需求,对于不同的分类有不同的类型。根据双向绑定的规则,我们只需要修改ViewModel
中TypeList
的内容就可以了。
注意: ObservableCollection
只有在列表项发生变化时才会触发页面刷新,即新增或删除时才会反应到页面上。若采用直接赋值的写法,不会触发页面刷新。
推荐更新数据时候的写法:
//清空原先的列表
TypeList.Clear();
list.ForEach(d =>
{
TypeList.Add(d);
});
TreeView.SelectedItem双向绑定
TreeView.SelectedItem
是ReadOnly
的,所以不能通过简单的绑定方法去获取选中项
最终还是要通过绑定Treeview
的SelectedItemChanged
事件,来修改ViewModel
中的数据
1.直接绑定事件
private void TreeView_OnSelectedItemChanged(object sender, RoutedPropertyChangedEventArgs
2.通过Command
绑定事件
- 在项目中引用
System.Windows.Interactivity.WPF
(简单来说该插件可以将页面控件的Event
转为ViewModel中的Command
) - 在窗体中添加引用
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
- 绑定
Command
到SelectedItemChanged
事件
ViewModel:
public class TreeViewModel : ViewModelBase
{
public ObservableCollection TypeList;
private TypeModel selectItem;
public TypeModel SelectItem
{
get { return selectItem; }
set { this.MutateVerbose(ref selectItem, value, RaisePropertyChanged()); }
}
public TreeViewModel()
{
TypeList = GetData();
}
public ICommand SelectItemChangeCommand
{
get
{
return new CommandBase((param) =>
{
if(param != null)
SelectItem = (TypeModel)param;
});
}
}
}
ViewModelBase
和CommandBase
是自己封装的基类,就是为了写WPF的双向绑定简单点,有兴趣的可以评论向我要。
Demo地址: https://github.com/fxhui/TreeViewDemo