欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Seaching TreeVIew WPF

程序员文章站 2022-03-29 10:26:01
项目中有一个树形结构的资源,需要支持搜索功能,搜索出来的结果还是需要按照树形结构展示,下面是简单实现的demo。 1.首先创建TreeViewItem的ViewModel,一般情况下,树形结构都包含DisplayName,Deepth,Parent,Children,Id, IndexCode,Vi ......

项目中有一个树形结构的资源,需要支持搜索功能,搜索出来的结果还是需要按照树形结构展示,下面是简单实现的demo。

1.首先创建treeviewitem的viewmodel,一般情况下,树形结构都包含displayname,deepth,parent,children,id, indexcode,visibility等属性,具体代码如下所示:

  1 using system;
  2 using system.collections.generic;
  3 using system.collections.objectmodel;
  4 using system.linq;
  5 using system.text;
  6 using system.threading.tasks;
  7 using system.windows;
  8 
  9 namespace treeviewdemo
 10 {
 11     public class treeviewitemvm : notifypropertychangedbase
 12     {
 13         public treeviewitemvm ()
 14         {
 15             visible = visibility.visible;
 16         }
 17 
 18         private treeviewitemvm parent;
 19         public treeviewitemvm parent
 20         {
 21             get
 22             {
 23                 return this.parent;
 24             }
 25             set
 26             {
 27                 if (this.parent != value)
 28                 {
 29                     this.parent = value;
 30                     this.onpropertychanged(() => this.parent);
 31                 }
 32             }
 33         }
 34 
 35         private observablecollection<treeviewitemvm> children;
 36         public observablecollection<treeviewitemvm> children
 37         {
 38             get
 39             {
 40                 return this.children;
 41             }
 42             set
 43             {
 44                 if (this.children != value)
 45                 {
 46                     this.children = value;
 47                     this.onpropertychanged(() => this.children);
 48                 }
 49             }
 50         }
 51 
 52         private string id;
 53         public string id
 54         {
 55             get
 56             {
 57                 return this.id;
 58             }
 59             set
 60             {
 61                 if (this.id != value)
 62                 {
 63                     this.id = value;
 64                     this.onpropertychanged(() => this.id);
 65                 }
 66             }
 67         }
 68 
 69         private string indexcode;
 70         public string indexcode
 71         {
 72             get { return indexcode; }
 73             set
 74             {
 75                 if (indexcode != value)
 76                 {
 77                     indexcode = value;
 78                     this.onpropertychanged(() => indexcode);
 79                 }
 80             }
 81         }
 82 
 83         private string displayname;
 84         public string displayname
 85         {
 86             get
 87             {
 88                 return this.displayname;
 89             }
 90             set
 91             {
 92                 if (this.displayname != value)
 93                 {
 94                     this.displayname = value;
 95                     this.onpropertychanged(() => this.displayname);
 96                 }
 97             }
 98         }
 99 
100         private int deepth;
101         public int deepth
102         {
103             get
104             {
105                 return this.deepth;
106             }
107             set
108             {
109                 if (this.deepth != value)
110                 {
111                     this.deepth = value;
112                     this.onpropertychanged(() => this.deepth);
113                 }
114             }
115         }
116 
117         private bool haschildren;
118         public bool haschildren
119         {
120             get
121             {
122                 return this.haschildren;
123             }
124             set
125             {
126                 if (this.haschildren != value)
127                 {
128                     this.haschildren = value;
129                     this.onpropertychanged(() => this.haschildren);
130                 }
131             }
132         }
133 
134         private nodetype type;
135         public nodetype type
136         {
137             get { return type; }
138             set
139             {
140                 if (type != value)
141                 {
142                     type = value;
143                     onpropertychanged(() => this.type);
144                 }
145             }
146         }
147 
148         private visibility visible;
149         public visibility visible
150         {
151             get { return visible; }
152             set
153             {
154                 if (visible != value)
155                 {
156                     visible = value;
157                     onpropertychanged(() => this.visible);
158                 }
159             }
160         }
161 
162         public bool namecontains(string filter)
163         {
164             if (string.isnullorwhitespace(filter))
165             {
166                 return true;
167             }
168 
169             return displayname.tolowerinvariant().contains(filter.tolowerinvariant());
170         }
171     }
172 }

2.创建treeviewviewmodel,其中定义了用于过滤的属性filter,以及过滤函数,并在构造函数中初始化一些测试数据,具体代码如下:

  1 using system;
  2 using system.collections.generic;
  3 using system.collections.objectmodel;
  4 using system.componentmodel;
  5 using system.linq;
  6 using system.text;
  7 using system.threading.tasks;
  8 using system.windows.data;
  9 
 10 namespace treeviewdemo
 11 {
 12     public class treeviewviewmodel : notifypropertychangedbase
 13     {
 14         public static treeviewviewmodel instance = new treeviewviewmodel();
 15 
 16         private treeviewviewmodel()
 17         {
 18             filter = string.empty;
 19 
 20             root = new treeviewitemvm()
 21             {
 22                 deepth = 0,
 23                 displayname = "五号线",
 24                 haschildren = true,
 25                 type = nodetype.unit,
 26                 id = "0",
 27                 children = new observablecollection<treeviewitemvm>() { 
 28                     new treeviewitemvm() { displayname = "站台", deepth = 1, haschildren = true, id = "1", type = nodetype.region,
 29                         children = new observablecollection<treeviewitemvm>(){
 30                             new treeviewitemvm() { displayname = "camera 01", deepth = 2, haschildren = false, id = "3",type = nodetype.camera },
 31                             new treeviewitemvm() { displayname = "camera 02", deepth = 2, haschildren = false, id = "4",type = nodetype.camera },
 32                             new treeviewitemvm() { displayname = "camera 03", deepth = 2, haschildren = false, id = "5",type = nodetype.camera },
 33                             new treeviewitemvm() { displayname = "camera 04", deepth = 2, haschildren = false, id = "6",type = nodetype.camera },
 34                             new treeviewitemvm() { displayname = "camera 05", deepth = 2, haschildren = false, id = "7", type = nodetype.camera},
 35                         }},
 36                     new treeviewitemvm() { displayname = "进出口", deepth = 1, haschildren = true, id = "10", type = nodetype.region,
 37                         children = new observablecollection<treeviewitemvm>(){
 38                             new treeviewitemvm() { displayname = "camera 11", deepth = 2, haschildren = false, id = "13",type = nodetype.camera },
 39                             new treeviewitemvm() { displayname = "camera 12", deepth = 2, haschildren = false, id = "14",type = nodetype.camera },
 40                             new treeviewitemvm() { displayname = "camera 13", deepth = 2, haschildren = false, id = "15",type = nodetype.camera },
 41                             new treeviewitemvm() { displayname = "camera 14", deepth = 2, haschildren = false, id = "16", type = nodetype.camera},
 42                             new treeviewitemvm() { displayname = "camera 15", deepth = 2, haschildren = false, id = "17", type = nodetype.camera},
 43                         }},
 44                 }
 45             };
 46 
 47             inittreeview();
 48         }
 49 
 50         private observablecollection<treeviewitemvm> selectedcameras = new observablecollection<treeviewitemvm>();
 51 
 52         private treeviewitemvm root;
 53         public treeviewitemvm root
 54         {
 55             get
 56             {
 57                 return this.root;
 58             }
 59             set
 60             {
 61                 if (this.root != value)
 62                 {
 63                     this.root = value;
 64                     this.onpropertychanged(() => this.root);
 65                 }
 66             }
 67         }
 68 
 69         /// <summary>
 70         /// 过滤字段
 71         /// </summary>
 72         private string filter;
 73         public string filter
 74         {
 75             get
 76             {
 77                 return this.filter;
 78             }
 79             set
 80             {
 81                 if (this.filter != value)
 82                 {
 83 
 84                     this.filter = value;
 85                     this.onpropertychanged(() => this.filter);
 86 
 87                     this.refresh();
 88                 }
 89             }
 90         }
 91 
 92         /// <summary>
 93         /// view
 94         /// </summary>
 95         protected icollectionview view;
 96         public icollectionview view
 97         {
 98             get
 99             {
100                 return this.view;
101             }
102             set
103             {
104                 if (this.view != value)
105                 {
106                     this.view = value;
107                     this.onpropertychanged(() => this.view);
108                 }
109             }
110         }
111 
112         /// <summary>
113         /// 刷新view
114         /// </summary>
115         public void refresh()
116         {
117             if (this.view != null)
118             {
119                 this.view.refresh();
120             }
121         }
122 
123         private bool dofilter(object obj)
124         {
125             treeviewitemvm item = obj as treeviewitemvm;
126             if (item == null)
127             {
128                 return true;
129             }
130 
131             bool result = false;
132             foreach (var node in item.children)
133             {
134                 result = treeitemdofilter(node) || result;
135             }
136 
137             return result || item.namecontains(this.filter);
138         }
139 
140         private bool treeitemdofilter(treeviewitemvm vm)
141         {
142             if (vm == null)
143             {
144                 return true;
145             }
146 
147             bool result = false;
148             if (vm.type == nodetype.region || vm.type == nodetype.unit)
149             {
150                 foreach (var item in vm.children)
151                 {
152                     result = treeitemdofilter(item) || result;
153                 }
154             }
155 
156             if (result || vm.namecontains(this.filter))
157             {
158                 result = true;
159                 vm.visible = system.windows.visibility.visible;
160             }
161             else
162             {
163                 vm.visible = system.windows.visibility.collapsed;
164             }
165 
166             return result;
167         }
168 
169         public void inittreeview()
170         {
171             this.view = collectionviewsource.getdefaultview(this.root.children);
172             this.view.filter = this.dofilter;
173             this.refresh();
174         }
175     }
176 }

3.在界面添加一个treeview,并添加一个简单的style,将viewmodel中必要数据进行绑定:

 1 <window x:class="treeviewdemo.mainwindow"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         title="mainwindow" height="450" width="525">
 5     <window.resources>
 6         <style x:key="style" targettype="{x:type treeviewitem}">
 7             <setter property="template">
 8                 <setter.value>
 9                     <controltemplate targettype="{x:type treeviewitem}">
10                         <grid visibility="{binding visible}" background="{binding background}">
11                             <contentpresenter contentsource="header"/>
12                         </grid>
13                         
14                         <controltemplate.triggers>
15                             <trigger property="isselected" value="true">
16                                 <setter property="background" value="green"/>
17                             </trigger>
18                         </controltemplate.triggers>
19                     </controltemplate>
20                 </setter.value>
21             </setter>
22         </style>
23     </window.resources>
24     <grid>
25         <grid.rowdefinitions>
26             <rowdefinition height="auto"/>
27             <rowdefinition height="*"/>
28         </grid.rowdefinitions>
29 
30         <textbox x:name="searchtxt" width="200" horizontalalignment="center" height="40"
31                  margin="20" text="{binding filter, mode=twoway, updatesourcetrigger=propertychanged}"/>
32 
33         <treeview
34                   grid.row="1"
35                   itemssource="{binding view}">
36             <treeview.itemtemplate>
37                 <hierarchicaldatatemplate itemcontainerstyle ="{staticresource style}"  itemssource="{binding children}">
38                     <grid height="25" >
39                         <textblock
40                             x:name="txt"
41                             verticalalignment="center"
42                             text="{binding displayname}"    
43                             texttrimming="characterellipsis"
44                             tooltip="{binding displayname}" />
45                     </grid>
46                 </hierarchicaldatatemplate>
47             </treeview.itemtemplate>
48         </treeview>
49     </grid>
50 </window>

4.在给界面绑定具体的数据

 1 using system.windows;
 2 
 3 namespace treeviewdemo
 4 {
 5     /// <summary>
 6     /// mainwindow.xaml 的交互逻辑
 7     /// </summary>
 8     public partial class mainwindow : window
 9     {
10         public mainwindow()
11         {
12             initializecomponent();
13             this.loaded += mainwindow_loaded;
14         }
15 
16         void mainwindow_loaded(object sender, routedeventargs e)
17         {
18             this.datacontext = treeviewviewmodel.instance;
19         }
20     }
21 }

5.运行结果:

 Seaching TreeVIew WPF

Seaching TreeVIew WPF