博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
自定义ListBox,实现单多选切换(复选框)
阅读量:6984 次
发布时间:2019-06-27

本文共 26441 字,大约阅读时间需要 88 分钟。

今天花了一天的时间收集了一些关于ListBox多选功能的文章研究了一下,并实现了自己的ListBox多选效果。

下面先分享一下我收集的几篇ListBox多选功能的文章:

(1)卤面网: 的文章:

(2)卤面网: 的文章:

(3)博客园: 的文章:

接着说下自己所做的Listbox多选控件,我现在把它命名为SinOrMulListBox:

(1)声明一个类SinOrMulListBox,让它继承自ListBox。

    同时定义一个依赖属性IsMultipleSelect便于我们在单选和多选之间切换。

    由于ListBox的默认容器是ListBoxItem,而我们要在容器中添加一个复选框,所以为了方便我们定义一个自己的默认容器暂命名为SinOrMulListBoxItem。要在我们的SinOrMulListBox使用自己的容器SinOrMulListBoxItem则需要重写父类ListBox里的两个函数:GetContainerForItemOverride()IsItemItsOwnContainerOverride(object item)

主要代码:

Generic.xaml       默认样式如下:

1 
5 6
7
114 115
116
134 135

  其中SinOrMulListBox的样式其实和ListBox是一样的,我们主要修改是继承ListBoxItem的容器控件SinOrMulListBoxItem的样式;而在SinOrMulListBoxItem容器中我们在原有的ListBoxItem样式中添加了一个复选框,并添加一个状态分组MultiSelectionStates让SinOrMulListBox在单多选中切换,为了切换效果平滑过渡,我们添加了一个过渡动画

 

SinOrMulListBox.cs      主要代码如下:

1 using tool; 2 using System; 3 using System.Windows; 4 using System.Windows.Controls; 5  6 namespace SinOrMulListBox 7 { 8     [StyleTypedProperty(Property = "ItemContainerStyle", StyleTargetType = typeof(SinOrMulListBoxItem))] 9     public class SinOrMulListBox : ListBox10     {11         public SinOrMulListBox()12         {13             DefaultStyleKey = typeof(SinOrMulListBox);14         }15 16         #region Rewrite the superclass method17 18         protected override DependencyObject GetContainerForItemOverride()19         {20             var item = new SinOrMulListBoxItem();21             if (ItemContainerStyle != null)22                 item.Style = ItemContainerStyle;23             return item;24         }25         protected override bool IsItemItsOwnContainerOverride(object item)26         {27             bool nBool = item is SinOrMulListBoxItem;28 29             return nBool;30         }31 32         public override void OnApplyTemplate()33         {34             base.OnApplyTemplate();35             IsMultipleSelect = SelectionMode != SelectionMode.Single;36         }37 38         #endregion39 40         #region Custom fuction41 42         /// 43         /// Don't all selected .44         /// 45         public void UnSelectAll()46         {47             var items = this.Descendants
();48 SelectedItem = null;49 items.ForEachEx(t => t.IsSelected = false);//t.CanCheck50 }51 52 #endregion53 54 #region Custom DependencyObject55 ///
56 /// Whether can choose more options?57 /// 58 public bool IsMultipleSelect59 {60 get { return (bool)GetValue(IsMultipleSelectProperty); }61 set { SetValue(IsMultipleSelectProperty, value); }62 }63 64 public static readonly DependencyProperty IsMultipleSelectProperty =65 DependencyProperty.Register("IsMultipleSelect", typeof(bool), typeof(SinOrMulListBox), new PropertyMetadata(false, OnIsMultipleSelectPropertyChanged));66 67 private static void OnIsMultipleSelectPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)68 {69 var listBox = sender as SinOrMulListBox;70 //Debug.Assert(listBox != null);71 listBox.OnIsMultipleSelectChanged();72 }73 74 private void OnIsMultipleSelectChanged()75 {76 var items = this.Descendants
();77 if (IsMultipleSelect)78 {79 SelectionMode = SelectionMode.Multiple;80 items.ForEachEx(t => t.CanCheck = true);81 }82 else83 {84 SelectionMode = SelectionMode.Single;85 SelectedItem = null;86 items.ForEachEx(t => t.CanCheck = false);87 }88 }89 #endregion90 }91 }

   这里面我额外添加了一个方法UnSelectAll(),用于对应继承ListBox的方法SelectAll(),实现全部不选择。

   在OnIsMultipleSelectChanged()中items.ForEachEx(t => t.CanCheck = false)来启动SinOrMulListBoxItem中复选框的显示与不显示动画

 (2)声明一个类SinOrMulListBoxItem,让它继承自ListBoxItem。

    同时定义一个依赖属性CanCheck便于我们在单选和多选之间切换,并启动过渡动画。

    CheckBox的IsChecked绑定ListBoxItem的IsSelected属性,通过ListBox.SelectItems取出选中集合

 

SinOrMulListBoxItem.cs      主要代码如下:

View Code
1 using tool; 2 using System; 3 using System.Linq; 4 using System.Windows; 5 using System.Windows.Media; 6 using System.Windows.Controls; 7  8 namespace SinOrMulListBox 9 {10     11     public class SinOrMulListBoxItem : ListBoxItem12     {13         public SinOrMulListBoxItem()14         {15             DefaultStyleKey = typeof(SinOrMulListBoxItem);16         }17 18         public override void OnApplyTemplate()19         {20             base.OnApplyTemplate();21         }22 23         #region Custom DependencyProperty24         /// 25         /// Is used check box ?26         /// 27         internal bool CanCheck28         {29             get { return (bool)GetValue(CanCheckProperty); }30             set { SetValue(CanCheckProperty, value); }31         }32 33         internal static readonly DependencyProperty CanCheckProperty =34             DependencyProperty.Register("CanCheck", typeof(bool), typeof(SinOrMulListBoxItem), new PropertyMetadata(false, OnCanCheckPropertyChanged));35 36         private static void OnCanCheckPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)37         {38             var item = sender as SinOrMulListBoxItem;39             //Debug.Assert(item != null);40             item.OnCanCheckChanged();41         }42 43         private void OnCanCheckChanged()44         {45             VisualStateManager.GoToState(this, CanCheck ? "EnableSelection" : "DisableSelection", true);46         }47         #endregion 48     }49 50     public class StaticFunction51     {52         /// 53         /// Find father control54         /// 55         /// 
56 /// 57 ///
58 public static T FindParentOfType
(DependencyObject obj) where T : FrameworkElement59 {60 DependencyObject parent = VisualTreeHelper.GetParent(obj);61 while (parent != null)62 {63 if (parent is T)64 {65 return (T)parent;66 }67 parent = VisualTreeHelper.GetParent(parent);68 }69 return null;70 }71 }72 }

  注意:到这其实应该说所有所有功能都OK了,可运行后发现个问题~~~~(>_<)~~~~   在显示区内的SinOrMulListBoxItem没有问题,但在显示区外的SinOrMulListBoxItem有的显示复选框有的不显示复选框,而功能什么运行使用又都正常,很郁闷。根据这些现象我猜测问题出现在ListBox本身的虚拟化机制上,也就是说,当SinOrMulListBoxItem在显示区时候才会new而不在显示区的SinOrMulListBoxItem是不会new出来的。因此我们应该让在显示区外的SinOrMulListBoxItem被new的时候知道自己是否应该显示复选框,为此我们添加了一些代码解决这一问题。下面是解决后的完整代码:

1 using tool; 2 using System; 3 using System.Linq; 4 using System.Windows; 5 using System.Windows.Media; 6 using System.Windows.Controls; 7  8 namespace SinOrMulListBox 9 {10     11     public class SinOrMulListBoxItem : ListBoxItem12     {13         public SinOrMulListBoxItem()14         {15             DefaultStyleKey = typeof(SinOrMulListBoxItem);16 17             Loaded += SinOrMulListBoxItem_Loaded;18         }19 20         public override void OnApplyTemplate()21         {22             base.OnApplyTemplate();23         }24 25         #region Custom DependencyProperty26         /// 27         /// Is used check box ?28         /// 29         internal bool CanCheck30         {31             get { return (bool)GetValue(CanCheckProperty); }32             set { SetValue(CanCheckProperty, value); }33         }34 35         internal static readonly DependencyProperty CanCheckProperty =36             DependencyProperty.Register("CanCheck", typeof(bool), typeof(SinOrMulListBoxItem), new PropertyMetadata(false, OnCanCheckPropertyChanged));37 38         private static void OnCanCheckPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)39         {40             var item = sender as SinOrMulListBoxItem;41             //Debug.Assert(item != null);42             item.OnCanCheckChanged();43         }44 45         private void OnCanCheckChanged()46         {47             VisualStateManager.GoToState(this, CanCheck ? "EnableSelection" : "DisableSelection", true);48         }49         #endregion 50 51         private SinOrMulListBox _listBox;52         private SinOrMulListBox ListBox53         {54             get { return _listBox ?? (_listBox = this.Ancestors
().FirstOrDefault()); }55 }56 57 void SinOrMulListBoxItem_Loaded(object sender, RoutedEventArgs e)58 {59 CanCheck = ListBox.IsMultipleSelect;60 }61 }62 63 public class StaticFunction64 {65 ///
66 /// Find father control67 /// 68 ///
69 ///
70 ///
71 public static T FindParentOfType
(DependencyObject obj) where T : FrameworkElement72 {73 DependencyObject parent = VisualTreeHelper.GetParent(obj);74 while (parent != null)75 {76 if (parent is T)77 {78 return (T)parent;79 }80 parent = VisualTreeHelper.GetParent(parent);81 }82 return null;83 }84 }85 }

  在这里再附上子父控件的查找类,这个是从 中拷贝的。

TreeExtensions.cs     所有代码:

View Code
1 using System;  2 using System.Linq;  3 using System.Windows;  4 using System.Windows.Data;  5 using System.Windows.Media;  6 using System.Collections.Generic;  7   8 namespace tool  9 { 10     public static class TreeExtensions 11     { 12         ///  13         /// 返回可视树中所有子代元素集合(不包括本身) 14         ///  15         public static IEnumerable
Descendants(this DependencyObject item) 16 { 17 foreach (var child in item.ChildrenEx()) 18 { 19 yield return child; 20 21 foreach (var grandChild in child.Descendants()) 22 { 23 yield return grandChild; 24 } 25 } 26 } 27 28 ///
29 /// 返回可视树中所有子代元素集合(包括本身) 30 /// 31 public static IEnumerable
DescendantsAndSelf(this DependencyObject item) 32 { 33 yield return item; 34 35 foreach (var child in item.Descendants()) 36 { 37 yield return child; 38 } 39 } 40 41 ///
42 /// 返回可视树中所有父代元素集合(不包括本身) 43 /// 44 public static IEnumerable
Ancestors(this DependencyObject item) 45 { 46 var parent = item.ParentEx(); 47 while (parent != null) 48 { 49 yield return parent; 50 parent = parent.ParentEx(); 51 } 52 } 53 54 ///
55 /// 返回可视树中所有父代元素集合(包括本身) 56 /// 57 public static IEnumerable
AncestorsAndSelf(this DependencyObject item) 58 { 59 yield return item; 60 61 foreach (var ancestor in item.Ancestors()) 62 { 63 yield return ancestor; 64 } 65 } 66 67 ///
68 /// 返回可视树中下一代所有的子元素(不包括自身) 69 /// 70 public static IEnumerable
Elements(this DependencyObject item) 71 { 72 return item.ChildrenEx(); 73 } 74 75 ///
76 /// 返回可视树中与该元素位于同一级别且文档顺序位于该元素前面的所有元素 77 /// 78 public static IEnumerable
ElementsBeforeSelf(this DependencyObject item) 79 { 80 var parent = item.ParentEx(); 81 if (parent == null) 82 yield break; 83 foreach (var child in item.Elements().TakeWhile(child => !child.Equals(item))) 84 { 85 yield return child; 86 } 87 } 88 89 ///
90 /// 返回可视树中与该元素位于同一级别且文档顺序位于该元素后面的所有元素 91 /// 92 public static IEnumerable
ElementsAfterSelf(this DependencyObject item) 93 { 94 var parent = item.ParentEx(); 95 if (parent == null) 96 yield break; 97 var afterSelf = false; 98 foreach (var child in parent.Elements()) 99 {100 if (afterSelf)101 yield return child;102 if (child.Equals(item))103 afterSelf = true;104 }105 }106 107 ///
108 /// 返回可视树中下一代所有的子元素(包括本身)109 /// 110 public static IEnumerable
ElementsAndSelf(this DependencyObject item)111 {112 yield return item;113 114 foreach (var child in item.Elements())115 {116 yield return child;117 }118 }119 120 ///
121 /// 返回可视树中所有子代中类型符合要求的元素集合(不包括自身)122 /// 123 public static IEnumerable
Descendants
(this DependencyObject item)124 {125 return item.Descendants().Where(i => i is T).Cast
();126 }127 128 ///
129 /// 返回可视树中与该元素位于同一级别且文档顺序位于该元素前面的符合类型要求的所有元素130 /// 131 public static IEnumerable
ElementsBeforeSelf
(this DependencyObject item)132 {133 return item.ElementsBeforeSelf().Where(i => i is T).Cast
();134 }135 136 ///
137 /// 返回可视树中与该元素位于同一级别且文档顺序位于该元素后面的符合类型要求的所有元素138 /// 139 public static IEnumerable
ElementsAfterSelf
(this DependencyObject item)140 {141 return item.ElementsAfterSelf().Where(i => i is T).Cast
();142 }143 144 ///
145 /// 返回可视树中所有子代中类型符合要求的元素集合(包括自身)146 /// 147 public static IEnumerable
DescendantsAndSelf
(this DependencyObject item)148 {149 return item.DescendantsAndSelf().Where(i => i is T).Cast
();150 }151 152 ///
153 /// 返回可视树中所有父代中类型符合要求的元素集合(不包括自身)154 /// 155 public static IEnumerable
Ancestors
(this DependencyObject item)156 {157 return item.Ancestors().Where(i => i is T).Cast
();158 }159 160 ///
161 /// 返回可视树中所有父代中类型符合要求的元素集合(包括自身)162 /// which match the given type.163 /// 164 public static IEnumerable
AncestorsAndSelf
(this DependencyObject item)165 {166 return item.AncestorsAndSelf().Where(i => i is T).Cast
();167 }168 169 ///
170 /// 返回可视树中下一代符合类型要求的所有子元素(不包括自身)171 /// 172 public static IEnumerable
Elements
(this DependencyObject item)173 {174 return item.Elements().Where(i => i is T).Cast
();175 }176 177 ///
178 /// 返回可视树中下一代符合类型要求的所有子元素(包括自身)179 /// 180 public static IEnumerable
ElementsAndSelf
(this DependencyObject item)181 {182 return item.ElementsAndSelf().Where(i => i is T).Cast
();183 }184 185 }186 187 public static class EnumerableTreeExtensions188 {189 ///
190 /// 对元素集合应用相同的函数,并返回该函数的结果集合191 /// 192 private static IEnumerable
DrillDown(this IEnumerable
items,193 Func
> function)194 {195 return items.SelectMany(function);196 }197 198 ///
199 /// 对元素集合应用相同的函数,并返回该函数结果符合类型要求的集合200 /// 201 public static IEnumerable
DrillDown
(this IEnumerable
items,202 Func
> function)203 where T : DependencyObject204 {205 return items.SelectMany(item => function(item).OfType
());206 }207 208 ///
209 /// 返回集合中所有的子代元素集合(不包括自身)210 /// 211 public static IEnumerable
Descendants(this IEnumerable
items)212 {213 return items.DrillDown(i => i.Descendants());214 }215 216 ///
217 /// 返回集合中所有的子代元素集合(包括自身)218 /// 219 public static IEnumerable
DescendantsAndSelf(this IEnumerable
items)220 {221 return items.DrillDown(i => i.DescendantsAndSelf());222 }223 224 ///
225 /// 返回集合中所有的父代元素集合(不包括自身)226 /// 227 public static IEnumerable
Ancestors(this IEnumerable
items)228 {229 return items.DrillDown(i => i.Ancestors());230 }231 232 ///
233 /// 返回集合中所有的父代元素集合(包括自身)234 /// 235 public static IEnumerable
AncestorsAndSelf(this IEnumerable
items)236 {237 return items.DrillDown(i => i.AncestorsAndSelf());238 }239 240 ///
241 /// Returns a collection of child elements.242 /// 243 public static IEnumerable
Elements(this IEnumerable
items)244 {245 return items.DrillDown(i => i.Elements());246 }247 248 ///
249 /// Returns a collection containing this element and all child elements.250 /// 251 public static IEnumerable
ElementsAndSelf(this IEnumerable
items)252 {253 return items.DrillDown(i => i.ElementsAndSelf());254 }255 256 ///
257 /// Returns a collection of descendant elements which match the given type.258 /// 259 public static IEnumerable
Descendants
(this IEnumerable
items)260 where T : DependencyObject261 {262 return items.DrillDown
(i => i.Descendants());263 }264 265 ///
266 /// Returns a collection containing this element and all descendant elements.267 /// which match the given type.268 /// 269 public static IEnumerable
DescendantsAndSelf
(this IEnumerable
items)270 where T : DependencyObject271 {272 return items.DrillDown
(i => i.DescendantsAndSelf());273 }274 275 ///
276 /// Returns a collection of ancestor elements which match the given type.277 /// 278 public static IEnumerable
Ancestors
(this IEnumerable
items)279 where T : DependencyObject280 {281 return items.DrillDown
(i => i.Ancestors());282 }283 284 ///
285 /// Returns a collection containing this element and all ancestor elements.286 /// which match the given type.287 /// 288 public static IEnumerable
AncestorsAndSelf
(this IEnumerable
items)289 where T : DependencyObject290 {291 return items.DrillDown
(i => i.AncestorsAndSelf());292 }293 294 ///
295 /// Returns a collection of child elements which match the given type.296 /// 297 public static IEnumerable
Elements
(this IEnumerable
items)298 where T : DependencyObject299 {300 return items.DrillDown
(i => i.Elements());301 }302 303 ///
304 /// Returns a collection containing this element and all child elements.305 /// which match the given type.306 /// 307 public static IEnumerable
ElementsAndSelf
(this IEnumerable
items)308 where T : DependencyObject309 {310 return items.DrillDown
(i => i.ElementsAndSelf());311 }312 }313 314 public static class CommonExtension315 {316 #region DependencyObject Extension317 318 #region 监听依赖属性变化319 private static readonly Dictionary
> _callbackDic = new Dictionary
>();320 private static readonly Dictionary
_propertyNames = new Dictionary
();321 322 ///
323 /// 添加依赖属性改变时的回调函数324 /// 325 ///
326 ///
327 ///
328 public static void AddPropertyChangedCallback(this DependencyObject obj, string propertyName, PropertyChangedCallback callback)329 {330 try331 {332 var attachName = "ListenAttached" + propertyName;333 if (!_callbackDic.ContainsKey(obj))334 {335 _callbackDic.Add(obj, new List
());336 }337 var infoList = _callbackDic[obj];338 var info = infoList.FirstOrDefault(t => t.PropertyName == attachName);339 if (info == null)340 {341 info = new PropertyCallbackInfo { PropertyName = attachName };342 var binding = new Binding(propertyName) { Source = obj };343 var pro = DependencyProperty.RegisterAttached(attachName, typeof(object), obj.GetType(), new PropertyMetadata(OnPropertyChanged));344 BindingOperations.SetBinding(obj, pro, binding);345 _propertyNames.Add(pro, attachName);346 infoList.Add(info);347 }348 info.Callbacks.Add(callback);349 }350 catch (Exception e)351 {352 //Debug.WriteLine("执行CommonExtension中的AddPropertyChangedCallback函数出错:" + e.Message);353 }354 }355 356 ///
357 /// 移除依赖属性改变时的回调函数358 /// 359 ///
360 ///
361 ///
362 public static void RemovePropertyChangedCallback(this DependencyObject obj, string propertyName, PropertyChangedCallback callback)363 {364 List
infoList;365 if (!_callbackDic.TryGetValue(obj, out infoList))366 return;367 var attachName = "ListenAttached" + propertyName;368 var info = infoList.FirstOrDefault(t => t.PropertyName == attachName);369 if (info == null)370 return;371 info.Callbacks.Remove(callback);372 }373 374 private static void OnPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)375 {376 string name;377 if (!_propertyNames.TryGetValue(e.Property, out name))378 return;379 List
infoList;380 if (!_callbackDic.TryGetValue(sender, out infoList))381 return;382 var info = infoList.FirstOrDefault(t => t.PropertyName == name);383 if (info == null)384 return;385 info.Callbacks.ForEach(t => t(sender, e));386 }387 388 private class PropertyCallbackInfo389 {390 public string PropertyName { get; set; }391 private readonly List
_callbacks = new List
();392 public List
Callbacks393 {394 get { return _callbacks; }395 }396 }397 #endregion398 399 ///
400 /// 返回可视树中该元素的所有子元素401 /// 402 ///
403 ///
404 public static IEnumerable
ChildrenEx(this DependencyObject item)405 {406 var childrenCount = VisualTreeHelper.GetChildrenCount(item);407 for (var i = 0; i < childrenCount; i++)408 {409 yield return VisualTreeHelper.GetChild(item, i);410 }411 }412 413 ///
414 /// 返回可视树中该元素的父元素415 /// 416 ///
417 ///
418 public static DependencyObject ParentEx(this DependencyObject item)419 {420 return VisualTreeHelper.GetParent(item);421 }422 #endregion423 424 #region IEnumerable Extension425 ///
426 /// 枚举中的每个对象执行相同的动作427 /// 428 ///
429 ///
430 ///
431 public static void ForEachEx
(this IEnumerable
items, Action
action)432 {433 foreach (var item in items)434 action(item);435 }436 437 ///
438 /// 枚举中的每个对象执行相同的动作439 /// 440 ///
枚举类型
441 ///
需要执行动作的类型
442 ///
443 ///
444 public static void ForEachEx
(this IEnumerable
items, Action
action)445 where S : class446 {447 foreach (var item in items.OfType())448 {449 action(item);450 }451 }452 453 #endregion454 }455 }

 

(3)下面是我们的测试代码。这个比较简单直接上代码

MainPage.xaml         主要代码

View Code
1 
15 16
17
18
19
20
21
22 23
24
25
26
27 28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45 46
47
48
49
50
51
52 53
54
55
56
57
58
59 60

MainPage.xaml.cs         主要代码

View Code
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Net; 5 using System.Windows; 6 using System.Windows.Controls; 7 using System.Windows.Documents; 8 using System.Windows.Input; 9 using System.Windows.Media;10 using System.Windows.Media.Animation;11 using System.Windows.Shapes;12 using Microsoft.Phone.Controls;13 14 namespace TestLstBoxDemo15 {16     public partial class MainPage : PhoneApplicationPage17     {18         // Constructor19         public MainPage()20         {21             InitializeComponent();22 23             this.Loaded += new RoutedEventHandler(MainPage_Loaded);24         }25 26         void MainPage_Loaded(object sender, RoutedEventArgs e)27         {28             DataContext = App.ViewModel;29         }30 31         protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)32         {33             if (!App.ViewModel.IsDataLoaded)34             {35                 App.ViewModel.LoadData();36             }37             base.OnNavigatedTo(e);38         }39 40         //查看选中所有选项41         private void ApplicationBarIconButton_Click(object sender, EventArgs e)42         {43             List
SelectedItems = new List
();44 foreach (var item in listBoxWithBoxes.SelectedItems)45 {46 SimpleModel nModel = item as SimpleModel;47 if (nModel != null)48 {49 SelectedItems.Add(nModel);50 }51 }52 }53 //全选54 private void ApplicationBarIconButton_Click_1(object sender, EventArgs e)55 {56 listBoxWithBoxes.SelectAll();57 }58 //全部不选59 private void ApplicationBarIconButton_Click_2(object sender, EventArgs e)60 {61 listBoxWithBoxes.UnSelectAll();62 }63 //开启单选64 private void ApplicationBarMenuItem_Click(object sender, EventArgs e)65 {66 listBoxWithBoxes.IsMultipleSelect = false;67 }68 //开启多选69 private void ApplicationBarMenuItem_Click_1(object sender, EventArgs e)70 {71 listBoxWithBoxes.IsMultipleSelect = true;72 }73 }74 }

ViewModel    主要代码

SimpleModel.cs
1 using System; 2 using System.Net; 3 using System.ComponentModel; 4  5 namespace TestLstBoxDemo 6 { 7     public class SimpleModel : INotifyPropertyChanged 8     { 9         protected string itsName;10         protected string itsDescription;11 12         public event PropertyChangedEventHandler PropertyChanged;13 14         public string Name15         {16             get { return this.itsName; }17             set { this.itsName = value; NotifyPropertyChanged("Name"); }18         }19 20 21         public string Description22         {23             get { return this.itsDescription; }24             set { this.itsDescription = value; NotifyPropertyChanged("Description"); }25         }26 27 28 29         protected void NotifyPropertyChanged(string thePropertyName)30         {31             if (this.PropertyChanged != null)32             {33                 this.PropertyChanged(this, new PropertyChangedEventArgs(thePropertyName));34             }35         }36 37     }38 }
ListModel.cs
1 using System; 2 using System.ComponentModel; 3 using System.Collections.ObjectModel; 4  5 namespace TestLstBoxDemo 6 { 7     public class ListModel : INotifyPropertyChanged 8     { 9         public event PropertyChangedEventHandler PropertyChanged;10 11         public ObservableCollection
SimpleModels { get; private set; }12 13 14 15 public bool IsDataLoaded { get; private set; }16 17 public ListModel()18 {19 this.SimpleModels = new ObservableCollection
();20 }21 22 23 ///
24 /// 加载数据25 /// 26 public void LoadData()27 {28 for (int i = 1; i < 30; i++)29 {30 this.SimpleModels.Add(new SimpleModel() { Name = "第" + i + "项", Description = "这是第" + i + "项数据" });31 }32 this.IsDataLoaded = true;33 }34 35 36 protected void NotifyPropertyChanged(string thePropertyName)37 {38 if (this.PropertyChanged != null)39 {40 this.PropertyChanged(this, new PropertyChangedEventArgs(thePropertyName));41 }42 }43 44 }45 }

这里使用了 的文章:中提到的小技巧,代码如下

ViewModelSampleData.xaml
1 
5 6
7
8
9
10 11

 

完整代码如下:

效果预览:

转载于:https://www.cnblogs.com/qq278360339/archive/2012/10/08/2715628.html

你可能感兴趣的文章
[Step By Step]SAP HANA PAL指数回归预测分析Exponential Regression编程实例EXPREGRESSION(模型)...
查看>>
VMware Data Recovery备份恢复vmware虚拟机
查看>>
solr多core的处理
查看>>
解决DeferredResult 使用 @ResponseBody 注解返回中文乱码
查看>>
C# WinForm开发系列 - TextBox
查看>>
28岁少帅统领旷视南京研究院,LAMDA魏秀参专访
查看>>
java文件传输
查看>>
Xen虚拟机迁移技术
查看>>
安装Sql Server 2005出现“性能监视器计数器要求”错误解决方法。
查看>>
[.NET领域驱动设计实战系列]专题八:DDD案例:网上书店分布式消息队列和分布式缓存的实现...
查看>>
Icomparer和Icomparable集合排序
查看>>
【poi xlsx报错】使用POI创建xlsx无法打开
查看>>
UNIX环境高级编程笔记之文件I/O
查看>>
DIV+CSS规范命名
查看>>
我的2013 Q.E.D
查看>>
2017 Multi-University Training Contest - Team 9 1002&&HDU 6162 Ch’s gift【树链部分+线段树】...
查看>>
4.5. Rspamd
查看>>
ArcMap中的名称冲突问题
查看>>
(转) 一张图解AlphaGo原理及弱点
查看>>
美联邦调查局 FBI 网站被黑,数千特工信息泄露
查看>>