本文将说明如何创建一个带全选复选框的列表控件。其效果如下图:
这个控件是由一个复选框(CheckBox)与一个列表视图组合而成。它的操作逻辑:
当选中"全选"时,列表中所有的项目都会被选中;反之,取消选中"全选"时,所有项都会被取消勾选。在列表中选中部分数据项目时,"全选"框会呈现不确定状态(不确定).由此看出,"全选"复选框与列表项中的复选框达到了双向控制的效果。
其设计思路:首先,创建自定义控件(检查列表视图),在其ControlTemplate中定义检验盒和列表视图,并为列表视图设置ItemTemplate,在其中增加检验盒控件,如下:
控件模板目标类型="{ x :类型控件: checklistview } "网格背景="{模板绑定背景} "网格。行定义行定义高度='自动'/行定义高度=' * '//网格。行定义复选框内容='全选/ListView x:Name='list '网格。行='1 '列表视图项目模板数据模板复选框//数据模板/列表视图.项目模板/列表视图/网格/控件模板其次,为控件添加两个依赖属性,其中一个为ItemsSource,即该控件所要接收的数据源,也即选择列表;本质上,这个数据源会指定给其内的列表视图。另外也需要一个属性IsSelectAllChecked表示是否选中全选复选框。
公共静态只读依赖属性被选中所有选中属性=依赖属性.注册(' IsSelectAllChecked ',类型为(布尔?),typeof(CheckListView),新属性元数据(false));公共静态只读依赖属性项目源属性=依赖属性.注册(“项目源”,类型的(对象)、类型的(检查列表视图)、新属性元数据(null));///摘要///返回或设置全选复选框的选中状态////汇总公共布尔?是否选中了selectall { get { return(bool?)GetValue(IsSelectAllCheckedProperty);} set { SetValue(IsselectAllcheckedProperty,value);} } ///摘要///数据源////摘要公共对象items source { get { return(object)GetVaLue(items source属性);} set { SetValue(ItemSourcePrOperty,value);} } 需要注意的一点是,作为一个自定义控件,我们必须考虑它的通用性,所以为了保证能设置各式各样的数据源(如用户列表、物品列表或xx名称列表),在这里定义一个数据接口,只要数据源中的数据项实现该接口,即可达到通用的效果。该接口定义如下:
公共接口ICheckItem { ///summary ///当前项是否选中////选择了summary bool { get;设置;} ///摘要///名称////摘要字符串名称{获取设置;} }最后,我们把刚才定的属性绑定的控件上,如下:
复选框内容='全选IsChecked=' {绑定被选择全部选中,相对源={相对源模板化父项},模式=双向} '/ListView x : name=' list ' Grid .row=' 1 ' items source=' {模板绑定项source } ' ListView .ItemTemplate数据模板复选框内容="{绑定名称}”IsChecked=“{选择了绑定}”//数据模板/列表视图。项目模板/列表视图接下来,实现具体操作:
首先,通过"全选"复选框来控制所有列表项:这里通过其点击事件来执行检查所有项目方法,在此方法中,会对数据源进行遍历,将其被选中属性设置为真实的或假的。代码如下:
复选框内容='全选IsChecked=' {绑定被选中,相对源={相对源模板化父项},模式=双向} ' i3360交互.触发器I :事件触发器事件名称=' Click ' ei : callmethod操作方法名称=' CheckAllItems '目标对象=' { Binding relative source={ relative source templated parent } } '//I :事件触发器/I 3360交互.触发器/CheckBox///summary///全选或清空所用选择////summary public void CheckAllItems(){ foreach(items source中的ICheckItem项作为IListICheckItem) { item .IsSelected=IsSelectAllChecked .HasValue?IsSelectAllChecked .值:为假;} }然后,通过选中或取消选中列表项时,更新"全选"复选框的状态:在数据模板中,我们也为检验盒的点击事件设置了要触发的方法UpdateSelectAllState,代码如下:
数据模板复选框内容=“{绑定名称}”IsChecked=“{选择了绑定}”i3360交互。触发器I :事件触发器事件名称=' Click ' ei : callmethod操作方法名称=' UpdateSelectAllState '目标对象=' { Binding relative source={ relative source AncestorType=control : checklistview } } '//I 3360事件触发器/I 3360交互.触发器/CheckBox/DataTemplate///summary///根据当前选择的个数来更新全选框的状态////summary public void UpdateSelectAllState(){ var items=items source as IListICheckItem;if(items==null){ return;} //获取列表项中被选中值为真实的的个数,并通过该值来确定IsSelectAllChecked的值整数=项目数.其中(项=项被选中).count();if (count==items .count){ is selectall checked=true;}否则if(count==0){ selectall被选中=false} else { is selectall checked=null } }这里也有两点需要提醒:
我一开始定义属性IsSelectAllChecked时,它的类型是弯曲件类型,那么,由于检验盒控件的IsChecked值为空时,它将呈现不确定状态,所以后来把它改为布尔?类型。
在XAML代码中可以看出,对事件以及事件的响应使用了行为,所以,需要添加引用系统。Windows.Interactivity.dll和微软。Expression.Interactions.dll两个库,并在XMAL头部添加如下命名空间的引用:
xmlns : ei=' http://架构。微软。com/expression/2010/interactions ' xmlns : I=' http://schemas。微软。' com/expression/2010/interaction '这样,这个控件就基本完成了,接下来是如何使用它。
首先,定义将要在列表中展示的数据项,并为它实现之前提到的ICheckItem接口,这里定义了一个用户类,如下:
公共类用户: BindableBase,ICheckItem {私有bool被选中;私有字符串名称;选择了公共bool {选择了get { return}设置{ SetProperty(ref isSelected,value);} }公共字符串名称{ get { return name}设置{ SetProperty(引用名称,值);} } }接下来在视图模型中定义一个列表listicechickitem,并添加数据,最后在用户界面上为其绑定ItemsSource属性即可,在此不再贴代码了,具体请参考源代码。
源码下载
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。