在WPF中实现带CheckBox的ComboBox控件,让ComboBox控件可以支持多选。

将ComboBox的ItemsSource属性Binding到一个Book的集合,

  1. public class Book
  2. {
  3. public string Name { get; set; }
  4. }
  1. <ComboBox ItemsSource="{Binding Path=Books}">
  2. <ComboBox.ItemTemplate>
  3. <DataTemplate DataType="{x:Type local:Book}">
  4. <StackPanel>
  5. <TextBlock Text="{Binding Name}" />
  6. </StackPanel>
  7. </DataTemplate>
  8. </ComboBox.ItemTemplate>
  9. </ComboBox>

显示效果如下:

为了让ComboBox支持CheckBox,和上面代码一样,修改ComboBox的DataTemplate,CheckBox的选中/非选中状态需要Binding到一个Bool型的Property上面。但是这个Property并不是Book的一个属性,所以新建一个BookEx类,增加一个IsChecked属性

  1. public class BookEx : ObservableObject
  2. {
  3. public Book Book { get; private set; }
  4.  
  5. private bool _isChecked;
  6.  
  7. public bool IsChecked
  8. {
  9. get
  10. {
  11. return _isChecked;
  12. }
  13. set
  14. {
  15. if(_isChecked != value)
  16. {
  17. _isChecked = value;
  18.  
  19. RaisePropertyChanged("IsChecked");
  20. }
  21. }
  22. }
  23.  
  24. public BookEx(Book book)
  25. {
  26. Book = book;
  27. }
  28. }

将ComboBox的ItemsSource属性Binding到BookEx集合上,下面修改ComboBox的DataTemplate:

此时已经可以实现多选了,但是当选择相应的条目后,在ComboBox的Text区域并不显示。下面来解决这个问题。实现方式是将选中的Book的Name属性集合Binding到ComboBox的Text属性上面。对ViewModel做一些改造,增加一个SelectedText属性,用来显示选中的条目Name集合

  1. public ObservableCollection<BookEx> BookExs
  2. {
  3. get
  4. {
  5. if(_books == null)
  6. {
  7. _books = new ObservableCollection<BookEx>();
  8.  
  9. _books.CollectionChanged += (sender, e) =>
  10. {
  11. if(e.OldItems != null)
  12. {
  13. foreach (BookEx bookEx in e.OldItems)
  14. {
  15. bookEx.PropertyChanged -= ItemPropertyChanged;
  16. }
  17. }
  18.  
  19. if(e.NewItems != null)
  20. {
  21. foreach (BookEx bookEx in e.NewItems)
  22. {
  23. bookEx.PropertyChanged += ItemPropertyChanged;
  24. }
  25. }
  26. };
  27. }
  28.  
  29. return _books;
  30. }
  31. }
  32.  
  33. private void ItemPropertyChanged(object sender, PropertyChangedEventArgs e)
  34. {
  35. if(e.PropertyName == "IsChecked")
  36. {
  37. BookEx bookEx = sender as BookEx;
  38.  
  39. if(bookEx != null)
  40. {
  41. IEnumerable<BookEx> bookExs = BookExs.Where(b => b.IsChecked == true);
  42.  
  43. StringBuilder builder = new StringBuilder();
  44.  
  45. foreach (BookEx item in bookExs)
  46. {
  47. builder.Append(item.Book.Name + " ");
  48. }
  49.  
  50. SelectedText = builder == null ? string.Empty : builder.ToString();
  51. }
  52. }
  53. }

最后一个注意点,修改ComboBox的IsEditable="True",只有这样才能接收Text的Binding。

  1. <ComboBox Text="{Binding SelectedText}" IsEditable="True" ItemsSource="{Binding Path=BookExs}">
  2. <ComboBox.ItemTemplate>
  3. <DataTemplate DataType="{x:Type local:BookEx}">
  4. <StackPanel Orientation="Horizontal">
  5. <CheckBox IsChecked="{Binding IsChecked}" />
  6. <TextBlock Text="{Binding Book.Name}" />
  7. </StackPanel>
  8. </DataTemplate>
  9. </ComboBox.ItemTemplate>
  10. </ComboBox>

实现的效果如下:

就这样一个可以多选的ComboBox就实现了。代码点击这里下载。

感谢您的阅读,如果您有其他实现方式,欢迎在评论区域点评,谢谢~

WPF中实现多选ComboBox控件的更多相关文章

  1. WPF中不规则窗体与WindowsFormsHost控件的兼容问题完美解决方案

    首先先得瑟一下,有关WPF中不规则窗体与WindowsFormsHost控件不兼容的问题,网上给出的解决方案不能满足所有的情况,是有特定条件的,比如  WPF中不规则窗体与WebBrowser控件的兼 ...

  2. WPF中不规则窗体与WebBrowser控件的兼容问题解决办法

    原文:WPF中不规则窗体与WebBrowser控件的兼容问题解决办法 引言 这几天受委托开发一个网络电视项目,要求初步先使用内嵌网页形式实现视频播放和选单,以后再考虑将网页中的所有功能整合进桌面程序. ...

  3. WPF 中动态创建和删除控件

    原文:WPF 中动态创建和删除控件 动态创建控件 1.容器控件.RegisterName("Name",要注册的控件)   //注册控件 2.容器控件.FindName(" ...

  4. 封装:WPF中可以绑定的BindPassWord控件

    原文:封装:WPF中可以绑定的BindPassWord控件 一.目的:本身自带的PassWord不支持绑定 二.Xaml部分 <UserControl x:Class="HeBianG ...

  5. WPF 中动态创建、删除控件,注册控件名字,根据名字查找控件

    动态创建控件 1.容器控件.RegisterName("Name",要注册的控件)   //注册控件 2.容器控件.FindName("Name") as  控 ...

  6. WPF中增加Month Calendar月历控件

    XAML代码:(这里使用了codeproject.com网站上的一个Dll,你可以在这里下载它:http://www.codeproject.com/cs/miscctrl/MonthCalendar ...

  7. tkinter中checkbutton多选框控件和variable用法(六)

    checkbutton控件 简单的实现多选: import tkinter wuya = tkinter.Tk() wuya.title("wuya") wuya.geometry ...

  8. 在WPF中的Canvas上实现控件的拖动、缩放

    如题,项目中需要实现使用鼠标拖动.缩放一个矩形框,WPF中没有现成的,那就自己造一个轮子:) 造轮子前先看看Windows自带的画图工具中是怎样做的,如下图: 在被拖动的矩形框四周有9个小框,可以从不 ...

  9. WPF中Expander的用法和控件模板详解

    一.Expander的用法 在WPF中,Expander是一个很实用的复合控件,可以很方便的实现下拉菜单和导航栏等功能.先介绍简单的用法,而后分析他的控件模板. <Window.Resource ...

随机推荐

  1. windows上将代码上传到Github

    Repository name: 仓库名称 Description(可选): 仓库描述介绍 Public, Private : 仓库权限(公开共享,私有或指定合作者) Initialize this ...

  2. 【WPF】在新线程上打开窗口

    当WPF应用程序运行时,默认会创建一个UI主线程(因为至少需要一个),并在该UI线程上启动消息循环.直到消息循环结束,应用程序就随即退出.那么,问题就来了,能不能创建新线程,然后在新线程上打开一个新窗 ...

  3. less中的变量

     [less中的变量]1.声明变量:@变量名:变量值:使用变量:@变量名:[less中变量的类型]1.数字 数字px2.字符串:无引号字符串 red blue 有引号 "haha" ...

  4. C/C++中对链表操作的理解&&实例分析

    链表概述 链表是一种常见的重要的数据结构.它是动态地进行存储分配的一种结构.它可以根据需要开辟内存单元.链表有一个“头指针”变量,以head表示,它存放一个地址.该地址指向一个元素.链表中每一个元素称 ...

  5. Linux常见命令语句

    查看当前目录: pwd 查看文件具体大小: ls -l 返回上一级: cd.. 返回根目录: cd / 创建一个隐藏文件 vim .test 显示隐藏文件:ls -a 编辑文件: 1.vim 文件名 ...

  6. Hibernate的一个简单应用例子

    Hibernate是一个开源的ORM框架,顾名思义,它的核心思想即ORM(Object Relational Mapping,对象关系映射),可以通过对象来操作数据库中的信息,据说开发者一开始是不太熟 ...

  7. Java试题

    1.不使用循环,等比数列输出整型 n.2n.4n.8n--当大于max时,反向输出8n.4n.2n.n. 例如 n=10,max=100. 输出: 10 20 40 80 80 40 20 10 解题 ...

  8. Sqlserver事务备份和还原实例

    create database mydb use mydb go create table account( id ), name ), balance float ) go select * fro ...

  9. Docker for windows10 配置镜像加速

    windows玩docker的时候,经常碰到这种问题: Error response from daemon: Get https://registry-1.docker.io/v2/: net/ht ...

  10. phpstudy:80端口被占用解决方案总结

    一开始因为要安装新的软件,同时也由于一直电脑很卡,所以直接重装系统,从WIN8变成WIN10,然后不知道为什么,phpstudy里面80端口被占用了!被占用了!现在找到了两种方法解决! 第一种 该端口 ...