实际项目中常常要实现有CheckBox列表框。但是WPF没有自带这样的一个控件,下面就用Style来实现这样的功能。而对于CheckBox列表框,又常常会有一个Select All的CheckBox来表示当前列表框的选择状态。这个功能也会被包含在下面的示例之中。效果如下图所示。

对于单纯的,没有后台数据绑定的情况下,这个功能可以用ItemContainerStyle来实现。代码如下:

CheckListBoxItemContainerStyle 

Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/--><Style x:Key="CheckListBoxItemContainerStyle"
TargetType="{x:Type ListBoxItem}">
<!--Set it un-focusable, becaues the CheckBox in it should be focusable and only it.-->
<Setter Property="Focusable" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<CheckBox Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}"
IsChecked="{Binding IsSelected, RelativeSource={RelativeSource TemplatedParent}}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

CheckListBoxItemContainerStyle

其中要对Content和ContentTemplate等属性进行绑定,以方便对其进行扩展,保证其通用性。这个Style一般会放在Application级别的Resource中。

对于有后台数据绑定的情况,一般会有双个属性要绑定,一个是CheckBox里的Content,一个是CheckBox的IsChecked。绑定的路径,只有在用一个Style的ListBox那里才知道,所以并不能写在这个Style里,否则会破坏这个Style的通用性。比较合理的方式是基于这个现有的Style进行修改。

对于下面的数据类。

DataItem Class

public class DataItem : INotifyPropertyChanged {     private string name;     private bool isEnabled;
    public string Name     {         get { return name; }         set         {             name = value;             OnPropertyChanged("Name");         }     }
    public bool IsEnabled     {         get { return isEnabled; }         set         {             isEnabled = value;             OnPropertyChanged("IsEnabled");         }     }
    #region INotifyPropertyChanged Members
    public event PropertyChangedEventHandler PropertyChanged;
    #endregion
    protected virtual void OnPropertyChanged(string propertyName)     {         PropertyChangedEventHandler temp = PropertyChanged;         if (temp != null)         {             temp(this, new PropertyChangedEventArgs(propertyName));         }     } }

我们需要下面这个有针对性的Style来应用数据绑定。

DataItemCheckListBoxStyle 

Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/--><Style x:Key="DataItemCheckListBoxStyle"
TargetType="{x:Type ListBox}"
BasedOn="{StaticResource {x:Type ListBox}}">
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="{x:Type ListBoxItem}"
BasedOn="{StaticResource CheckListBoxItemContainerStyle}">
<Setter Property="IsSelected"
Value="{Binding IsEnabled}"/>
<Setter Property="Margin" Value="2,2,0,0"/>
</Style>
</Setter.Value>
</Setter>
<Setter Property="SelectionMode" Value="Multiple"/>
</Style>

DataItemCheckListBoxStyle

在上面的Style中,使用了ItemTemplate来指定CheckBox里的Content绑定到的属性,并把ListBoxItem的IsSelected绑定数据的相应属性上。由于这个Style是针对特定数据写的,所以应当放置在使用这个Style的ListBox所在的Window的Resource中。

当然,也可以为ListBox添加两个绑定类型的Attached Property来实现一个通用的Style。不过这个Property一样要在使用的地方设置,其实没有太大区别。有兴趣的读者可以自己试一下。

对于Select All这个CheckBox而言,用Attached Property倒是很方便。给CheckBox添加一个SyncTarget属性指向要同步的ListBox,就可以在Window.xaml.cs之外的地方同步CheckBox和ListBox了。代码如下:

ToggleButtonProperty 

Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->public class ToggleButtonProperty
{
// Using a DependencyProperty as the backing store for SyncTarget. This enables animation, styling, binding, etc...
public static readonly DependencyProperty SyncTargetProperty =
DependencyProperty.RegisterAttached("SyncTarget", typeof(ListBox), typeof(ToggleButtonProperty), new UIPropertyMetadata(new PropertyChangedCallback(OnSyncTargetChanged))); public static ListBox GetSyncTarget(DependencyObject obj)
{
return obj.GetValue(SyncTargetProperty) as ListBox;
} public static void SetSyncTarget(DependencyObject obj, ListBox value)
{
obj.SetValue(SyncTargetProperty, value);
} private static void OnSyncTargetChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
ToggleButton checker = sender as ToggleButton;
if (checker == null)
{
throw new InvalidOperationException("SyncTarget property only works on ToggleButton.");
} ListBox targetList = e.NewValue as ListBox;
if (targetList == null)
{
throw new InvalidOperationException("Sync target must be a ListBox.");
} //TODO: Un-subscribe OldValue's Event. checker.Checked += (s, a) =>
{
targetList.SelectAll();
}; checker.Unchecked += (s, a) =>
{
targetList.UnselectAll();
}; targetList.SelectionChanged += (s, a) =>
{
checker.IsChecked = targetList.SelectedItems.Count == ? false :
targetList.SelectedItems.Count == targetList.Items.Count ? (bool?)true : null;
};
}
}

ToggleButtonProperty

使用方式也很简单。如下代码所示。

用法

Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/--><DockPanel Margin="12">
<CheckBox Content="Select All"
Margin="0,0,0,5"
DockPanel.Dock="Top"
ext:ToggleButtonProperty.SyncTarget="{Binding ElementName=checkListBox}"/>
<ListBox x:Name="checkListBox"
Style="{StaticResource DataItemCheckListBoxStyle}"
ItemsSource="{Binding Path=Items, ElementName=mainWindow}"/>
</DockPanel>

用法

完整的项目文件可以从这里下载

转载至http://www.cnblogs.com/nankezhishi/archive/2009/12/30/checkablelistbox.html

CheckListBox的实现方式分析的更多相关文章

  1. 4.总结近5周以来的github上的工作情况,以图表方式分析你小组的工作情况、存在的问题及解决的方案。(尤心心)

    4.总结近5周以来的github上的工作情况,以图表方式分析你小组的工作情况.存在的问题及解决的方案. (1)利用github本身的graphs可以清晰的看出小组成员在github上面的交互,可以直接 ...

  2. apigw鉴权分析(1-3)百度 AI - 鉴权方式分析

    http://ai.baidu.com/docs#/Begin/top 一.访问入口 二.鉴权方式分析 1.鉴权认证方式一 - access_token - 针对HTTP API调用者 2.鉴权认证方 ...

  3. apigw鉴权分析(1-1)阿里数加 - 鉴权方式分析

    一.访问方式 1.访问阿里云首页 https://www.aliyun.com/?utm_medium=text&utm_source=bdbrand&utm_campaign=bdb ...

  4. Wps 2013 拼音标注两种方式分析

    Wps 2013 拼音标注两种方式分析 太阳火神的漂亮人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一致"创作公用协议 转 ...

  5. Netty学习——Google Protobuf使用方式分析和环境搭建

    Google Protobuf使用方式分析 在RPC框架中,Google Protobuf是很常用的一个库,和Apache Thrift 是同款的用于进行序列化的第三方库.原理都是大同小异,无非就是使 ...

  6. 数据库join方式分析

    前言    不管是博客园还是CSDN,看到很多朋友对数据库的理解.认识还是没有突破一个瓶颈 ,而这个瓶颈往往只是一层窗纸,越过了你将看到一个新世界.    04.05年做项目的时候,用SQL Serv ...

  7. xamarin studio And linq 查询方式分析

    在 Windows 操作系统可以正常读取网络上的 https 数据流,在 Linux 操作系统中会失败:http://www.cnblogs.com/skyivben/archive/2012/03/ ...

  8. Apache Spark源码走读之7 -- Standalone部署方式分析

    欢迎转载,转载请注明出处,徽沪一郎. 楔子 在Spark源码走读系列之2中曾经提到Spark能以Standalone的方式来运行cluster,但没有对Application的提交与具体运行流程做详细 ...

  9. Android窗口管理服务WindowManagerService对窗口的组织方式分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/8498908 我们知道,在Android系统中, ...

随机推荐

  1. supervisor监控gearman任务

    安装supervisor方法,可以直接用 yum install supervisord ,但是版本可能会旧一点,可以参考官方的方法: easy_install supervisor http://s ...

  2. 互联网的寒冬来了,BAT都不社招了

    一 总理上次来到创业街,是四个月,要不就是五个月前了. 之后,全国创业形势一路走红,锣鼓喧天鞭炮齐鸣.大众创业万众创新,颇有大炼钢铁亩产万斤之势,尤其在媒体上. 再之后,2015 进入下半年,风投圈的 ...

  3. 微信中直接下载APK

    某天在微信中偶遇一个二维码,识别二维码竟然可以直接下载APK! 该二维码如下: 解码后获得地址:(在线解码工具) http://www.rmdown.com/newt66y.apk 这不就是个普通的A ...

  4. R语言之中文分词:实例

    一.说明 网上提供的一个例子,做了修改与订正. 二.程序 #调入分词的库 library("rJava") library("Rwordseg") #调入绘制词 ...

  5. ch2 MySQL 架构组成

    第 2 章 MySQL 架构组成 前言 麻雀虽小,五脏俱全.MySQL    虽然以简单著称,但其内部结构并不简单.本章从 MySQL 物理组成.逻辑组成,以及相关工具几个角度来介绍    MySQL ...

  6. js后退一直停留在当前页面或者禁止后退

    //禁用后退按钮 function stopHistoryGo() { //禁用回退 window.location.hash="no-back-button"; window.l ...

  7. Java开发者值得关注的7款新工具

    云计算.大数据地快速发展催生了不少热门的应用及工具.作为老牌语言Java,其生态圈也出来了一些有关云服务.监控.文档分享方面的工具.本文总结了7款较新的Java工具,大家不妨看下. 1. JClari ...

  8. 大型网站系统架构演化之路【mark】

    前言 一 个成熟的大型网站(如淘宝.天猫.腾讯等)的系统架构并不是一开始设计时就具备完整的高性能.高可用.高伸缩等特性的,它是随着用户量的增加,业务功能的 扩展逐渐演变完善的,在这个过程中,开发模式. ...

  9. WorkbookDesigner mvc里面返回file

    using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.We ...

  10. 修改dll版本号处理未能加载“******”,或找不到动态链接库依赖的项

    <dependentAssembly> <assemblyIdentity name="System.Web.WebPages" publicKeyToken=& ...