最近在写一个小工具的时候,遇到TreeView的层级显示,刚好我又用了MVVM模式,所以这里做个总结。
以前我是直接绑定XML数据到TreeView的,使用的XmlDataProvider,这次的数据是直接来自数据库的。
用到的都是HierarchicalDataTemplate
下面演示一下如何使用绑定实现TreeView的层级显示
1.创建一个ViewModelBase类,实现INotifyPropertyChanged
1 public class ViewModelBase : INotifyPropertyChanged
2 {
3 public event PropertyChangedEventHandler PropertyChanged;
4
5 public void RaiseChange(string propertyName)
6 {
7 PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
8 }
9 }
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
level1ChildList = new List(); -
- public List
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
level2ChildList = new List(); -
- public List
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,增加一个列表用于绑定,并构建测试数据列表。
1 public class MainWindowViewModel : ViewModelBase
2 {
3 private List hierarchicalTestList = new List();
4
5 public List HierarchicalTestList
6 {
7 get => hierarchicalTestList;
8 set
9 {
10 hierarchicalTestList = value;
11 RaiseChange("HierarchicalTestList");
12 }
13 }
14
15 public MainWindowViewModel()
16 {
17 for (int i = 0; i < 3; i++)
18 {
19 hierarchicalTestList.Add(new Level1($"层级1项目@{i}"));
20 }
21 }
22 }
设置Context
1 public partial class MainWindow : Window
2 {
3 public MainWindow()
4 {
5 InitializeComponent();
6 this.DataContext = new MainWindowViewModel();
7 }
8 }
4.将TreeView的ItemSource绑定到MainWindowViewModel的HierarchicalTestList
1
5.使用HierarchicalDataTemplate重新定义TreeView的ItemTemplate
这里其实就是一级一级的定义,比如第一级,使用ItemSource绑定它的下一级列表,然后用一个Label显示当前层级要显示的数据。依次定义多级即可。
6.运行效果

说明:
1.正式使用时,应该将List换成ObservableCollection
2.如果绑定的数据为空,不会生成树节点,而不是生成一个空节点。所以这种方式适用于不规则的 数据。