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

WPF TreeView IsExpanded 绑定不上的问题

程序员文章站 2022-04-08 11:38:24
最近项目上需要通过MVVM来控制TreeView,其中需要需要控制通过搜索来定位某个节点,正常逻辑下,首先通过需要在树上面找到该节点,然后选中该节点,并将该节点的父节点展开,这个时候需要通过MVVM来控制,需要绑定起来,只是一直没有binding上,代码如下: MVVM示例代码: 界面代码: 数据的 ......

最近项目上需要通过mvvm来控制treeview,其中需要需要控制通过搜索来定位某个节点,正常逻辑下,首先通过需要在树上面找到该节点,然后选中该节点,并将该节点的父节点展开,这个时候需要通过mvvm来控制,需要绑定起来,只是一直没有binding上,代码如下:

mvvm示例代码:

  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 
  8 namespace dragdrop
  9 {
 10     class dataitem : notifypropertybase, icloneable
 11     {
 12         public dataitem(string header, int deepth = 1)
 13         {
 14             header = header;
 15             deepth = deepth;
 16         }
 17 
 18         public object clone()
 19         {
 20             dataitem dataitem = new dataitem(header, deepth);
 21             dataitem.isexpanded = isexpanded;
 22             dataitem.isselected = isselected;
 23             dataitem.deepth = deepth;
 24             foreach (dataitem item in items)
 25                 dataitem.items.add((dataitem)item.clone());
 26             return dataitem;
 27         }
 28 
 29         private string header;
 30         public string header
 31         {
 32             get { return header; }
 33             set
 34             {
 35                 setproperty(ref header, value);
 36             }
 37         }
 38 
 39         private bool isselected;
 40         public bool isselected
 41         {
 42             get { return isselected; }
 43             set { setproperty(ref isselected, value); }
 44         }
 45 
 46         private bool isexpanded;
 47         public bool isexpanded
 48         {
 49             get { return isexpanded; }
 50             set
 51             {
 52                 setproperty(ref isexpanded, value);
 53                 console.writeline("{0}--{1}", header, isexpanded);
 54             }
 55         }
 56 
 57         private int deepth;
 58         public int deepth
 59         {
 60             get { return deepth; }
 61             set
 62             {
 63                 if (deepth != value)
 64                 {
 65                     deepth = value;
 66                     setproperty(ref deepth, value);
 67                 }
 68             }
 69         }
 70 
 71         private observablecollection<dataitem> mitems = null;
 72         public observablecollection<dataitem> items
 73         {
 74             get
 75             {
 76                 if (mitems == null)
 77                     mitems = new observablecollection<dataitem>();
 78                 return mitems;
 79             }
 80         }       
 81         
 82     }
 83 
 84     class data
 85     {
 86         private static data minstance = new data();
 87 
 88         public static data instance
 89         {
 90             get { return minstance; }
 91         }
 92 
 93         private observablecollection<dataitem> generatetreeviewitems()
 94         {
 95             observablecollection<dataitem> items = new observablecollection<dataitem>();
 96 
 97             dataitem item1 = new dataitem("treeviewitem1");
 98             item1.items.add(new dataitem("subitem1", item1.deepth));
 99             item1.items.add(new dataitem("subitem2", item1.deepth));
100             item1.items.add(new dataitem("subitem3", item1.deepth));
101             item1.items.add(new dataitem("subitem4", item1.deepth));
102             items.add(item1);
103 
104             dataitem item2 = new dataitem("treeviewitem2");
105             item2.items.add(new dataitem("subitem1", item2.deepth));
106             item2.items.add(new dataitem("subitem2", item2.deepth));
107             items.add(item2);
108 
109             dataitem item3 = new dataitem("treeviewitem3");
110             item3.items.add(new dataitem("subitem1", item3.deepth));
111             item3.items.add(new dataitem("subitem2", item3.deepth));
112             item3.items.add(new dataitem("subitem3", item3.deepth));
113             item3.items.add(new dataitem("subitem4", item3.deepth));
114             item3.items.add(new dataitem("subitem5", item3.deepth));
115             item3.items.add(new dataitem("subitem6", item3.deepth));
116             item3.items.add(new dataitem("subitem7", item3.deepth));
117             item3.items.add(new dataitem("subitem8", item3.deepth));
118             items.add(item3);
119 
120             return items;
121         }
122 
123         private observablecollection<dataitem> generatelistitems()
124         {
125             observablecollection<dataitem> items = new observablecollection<dataitem>();
126             items.add(new dataitem("listboxitem1"));
127             items.add(new dataitem("listboxitem2"));
128             items.add(new dataitem("listboxitem3"));
129             items.add(new dataitem("listboxitem4"));
130             items.add(new dataitem("listboxitem5"));
131             return items;
132         }
133 
134         public observablecollection<dataitem> treeviewitems
135         {
136             get
137             {
138                 if (mtreeviewitems == null)
139                     mtreeviewitems = generatetreeviewitems();
140                 return mtreeviewitems;
141             }
142         }
143 
144         public observablecollection<dataitem> listboxitems
145         {
146             get
147             {
148                 if (mlistboxitems == null)
149                     mlistboxitems = generatelistitems();
150                 return mlistboxitems;
151             }
152         }
153 
154         private observablecollection<dataitem> mtreeviewitems = null;
155         private observablecollection<dataitem> mlistboxitems = null;
156     }
157 }

界面代码:

 1 <window x:class="dragdrop.mainwindow"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 5         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 6         xmlns:local="clr-namespace:dragdrop"
 7         mc:ignorable="d"
 8         title="mainwindow" height="350" width="525">
 9     <window.resources>
10         <hierarchicaldatatemplate x:key="treeviewtemplate" datatype="{x:type local:dataitem}" itemssource="{binding items}">
11             <textblock text="{binding header}"/>
12         </hierarchicaldatatemplate>
13 
14         <style x:key="treeviewstyle" targettype="{x:type treeviewitem}">
15             <setter property="isselected" value="{binding isselected, mode=twoway, updatesourcetrigger=propertychanged}"/>
16             <setter property="isexpanded" value="{binding isexpanded, mode=twoway,updatesourcetrigger=propertychanged}"/>
17             <style.triggers>
18                 <datatrigger binding="{binding deepth}" value="1">
19                     <setter property="isexpanded" value="true"/>
20                 </datatrigger>
21             </style.triggers>
22         </style>
23     </window.resources>
24     <grid x:name="mtoplevelgrid">
25         <treeview x:name="mtreeview" grid.column="0"
26                   itemssource="{binding source={x:static local:data.instance}, path=treeviewitems}"
27                   itemtemplate="{staticresource treeviewtemplate}"
28                   itemcontainerstyle="{staticresource treeviewstyle}"/>
29     </grid>
30 </window>

数据的绑定没有问题,界面没有问题,奇怪的是isselected可以正常绑定,但是isexpanded就是不行,后来发现这两个属性唯一的区别就是在treeview的式样中

1 <style.triggers>
2      <datatrigger binding="{binding deepth}" value="1">
3            <setter property="isexpanded" value="true"/>
4       </datatrigger>
5 </style.triggers>

后面把这个datatrigger这段代码注释掉,编译一下,重新运行,isexpanded就可以正常绑定。后面自己思考了一下,mvvm模式实现将viewmodel与界面上面的显示绑定起来,实际上也就是使用了观察者模式,而trigger的原理应该和数据binding是一样的,而且这个trigger写在后面,可能直接把前面的绑定取代了,但是试了一下,将datatrigger放到前面,也还是绑定不上,这种可能性排除;个人猜测可能是trigger的优先级比较高,从而造成isexpanded一直binding不上去。