如何在WPF中使用MVVM实现TreeView的层级显示

最近在写一个小工具的时候,遇到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包含了一个属性

在构造函数中创建测试数据

复制代码
 1 namespace MVVMTreeViewHierarchical
 2 {
 3     public class Level1 : ViewModelBase
 4     {
 5         private string level1Item = "";
 6 
 7         public string Level1Item
 8         {
 9             get => level1Item;
10             set
11             {
12                 level1Item = value;
13                 RaiseChange("Level1Item");
14             }
15         }
16 
17         private List<Level2> level1ChildList = new List<Level2>();
18 
19         public List<Level2> Level1ChildList
20         {
21             get => level1ChildList;
22             set
23             {
24                 level1ChildList = value;
25                 RaiseChange("Level1ChildList");
26             }
27         }
28 
29         public Level1(string item)
30         {
31             //构建测试数据
32             level1Item = item;
33             for(int i = 0;i<3;i++)
34             {
35                 level1ChildList.Add(new Level2($"层级2项目@{i}"));
36             }
37         }
38     }
39 
40     public class Level2 : ViewModelBase
41     {
42         private string level2Item = "";
43 
44         public string Level2Item
45         {
46             get => level2Item;
47             set
48             {
49                 level2Item = value;
50                 RaiseChange("Level2Item");
51             }
52         }
53 
54         private List<Level3> level2ChildList = new List<Level3>();
55 
56         public List<Level3> Level2ChildList
57         {
58             get => level2ChildList;
59             set
60             {
61                 level2ChildList = value;
62                 RaiseChange("Level2ChildList");
63             }
64         }
65 
66         public Level2(string item)
67         {
68             //构建测试数据
69             level2Item = item;
70             for (int i = 0; i < 3; i++)
71             {
72                 level2ChildList.Add(new Level3($"层级3项目@{i}"));
73             }
74         }
75     }
76 
77     public class Level3 : ViewModelBase
78     {
79         private string level3Item = "";
80 
81         public string Level3Item
82         {
83             get => level3Item;
84             set
85             {
86                 level3Item = value;
87                 RaiseChange("Level3Item");
88             }
89         }
90 
91         public Level3(string item)
92         {
93             //构建测试数据
94             level3Item = item;      
95         }
96     }
97 }
复制代码

 

3.新建一个ViewModel类MainWindowViewModel,增加一个列表用于绑定,并构建测试数据列表。

复制代码
 1 public class MainWindowViewModel : ViewModelBase
 2     {
 3         private List<Level1> hierarchicalTestList = new List<Level1>();
 4 
 5         public List<Level1> 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  <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.如果绑定的数据为空,不会生成树节点,而不是生成一个空节点。所以这种方式适用于不规则的 数据。

posted @   zhaotianff  阅读(1136)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示