最近在写一个小工具的时候,遇到TreeView的层级显示,刚好我又用了MVVM模式,所以这里做个总结。
以前我是直接绑定XML数据到TreeView的,使用的XmlDataProvider,这次的数据是直接来自数据库的。
用到的都是HierarchicalDataTemplate
下面演示一下如何使用绑定实现TreeView的层级显示
1.创建一个ViewModelBase类,实现INotifyPropertyChanged
public class ViewModelBase : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; public void RaiseChange(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
2.创建模型
这里我建立 了三个层级 的数据
层级1包含了一个属性和一个层级2列表
层级2包含了一个属性和一个层级3列表
层级3包含了一个属性
在构造函数中创建测试数据
namespace MVVMTreeViewHierarchical { public class Level1 : ViewModelBase { private string level1Item = ""; public string Level1Item { get => level1Item; set { level1Item = value; RaiseChange("Level1Item"); } } private List<Level2> level1ChildList = new List<Level2>(); public List<Level2> Level1ChildList { get => level1ChildList; set { level1ChildList = value; RaiseChange("Level1ChildList"); } } public Level1(string item) { //构建测试数据 level1Item = item; for(int i = 0;i<3;i++) { level1ChildList.Add(new Level2($"层级2项目@{i}")); } } } public class Level2 : ViewModelBase { private string level2Item = ""; public string Level2Item { get => level2Item; set { level2Item = value; RaiseChange("Level2Item"); } } private List<Level3> level2ChildList = new List<Level3>(); public List<Level3> Level2ChildList { get => level2ChildList; set { level2ChildList = value; RaiseChange("Level2ChildList"); } } public Level2(string item) { //构建测试数据 level2Item = item; for (int i = 0; i < 3; i++) { level2ChildList.Add(new Level3($"层级3项目@{i}")); } } } public class Level3 : ViewModelBase { private string level3Item = ""; public string Level3Item { get => level3Item; set { level3Item = value; RaiseChange("Level3Item"); } } public Level3(string item) { //构建测试数据 level3Item = item; } } }
3.新建一个ViewModel类MainWindowViewModel,增加一个列表用于绑定,并构建测试数据列表。
public class MainWindowViewModel : ViewModelBase { private List<Level1> hierarchicalTestList = new List<Level1>(); public List<Level1> HierarchicalTestList { get => hierarchicalTestList; set { hierarchicalTestList = value; RaiseChange("HierarchicalTestList"); } } public MainWindowViewModel() { for (int i = 0; i < 3; i++) { hierarchicalTestList.Add(new Level1($"层级1项目@{i}")); } } }
设置Context
public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); this.DataContext = new MainWindowViewModel(); } }
4.将TreeView的ItemSource绑定到MainWindowViewModel的HierarchicalTestList
<TreeView ItemsSource="{Binding HierarchicalTestList}">
5.使用HierarchicalDataTemplate重新定义TreeView的ItemTemplate
这里其实就是一级一级的定义,比如第一级,使用ItemSource绑定它的下一级列表,然后用一个Label显示当前层级要显示的数据。依次定义多级即可。
<TreeView.ItemTemplate> <HierarchicalDataTemplate ItemsSource="{Binding Level1ChildList}" DataType="{x:Type local:Level1}"> <Label Content="{Binding Level1Item}"/> <HierarchicalDataTemplate.ItemTemplate> <HierarchicalDataTemplate ItemsSource="{Binding Level2ChildList}" DataType="{x:Type local:Level2}"> <Label Content="{Binding Level2Item}"/> <HierarchicalDataTemplate.ItemTemplate> <DataTemplate DataType="{x:Type local:Level3}"> <Label Content="{Binding Level3Item}"/> </DataTemplate> </HierarchicalDataTemplate.ItemTemplate> </HierarchicalDataTemplate> </HierarchicalDataTemplate.ItemTemplate> </HierarchicalDataTemplate> </TreeView.ItemTemplate>
6.运行效果
说明:
1.正式使用时,应该将List换成ObservableCollection
2.如果绑定的数据为空,不会生成树节点,而不是生成一个空节点。所以这种方式适用于不规则的 数据。
来自:https://www.cnblogs.com/zhaotianff/p/16869172.html