WPF中实现多选ComboBox控件
在WPF中实现带CheckBox的ComboBox控件,让ComboBox控件可以支持多选。
将ComboBox的ItemsSource属性Binding到一个Book的集合,
public class Book
{
public string Name { get; set; }
}
<ComboBox ItemsSource="{Binding Path=Books}">
<ComboBox.ItemTemplate>
<DataTemplate DataType="{x:Type local:Book}">
<StackPanel>
<TextBlock Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
显示效果如下:
为了让ComboBox支持CheckBox,和上面代码一样,修改ComboBox的DataTemplate,CheckBox的选中/非选中状态需要Binding到一个Bool型的Property上面。但是这个Property并不是Book的一个属性,所以新建一个BookEx类,增加一个IsChecked属性
public class BookEx : ObservableObject
{
public Book Book { get; private set; } private bool _isChecked; public bool IsChecked
{
get
{
return _isChecked;
}
set
{
if(_isChecked != value)
{
_isChecked = value; RaisePropertyChanged("IsChecked");
}
}
} public BookEx(Book book)
{
Book = book;
}
}
将ComboBox的ItemsSource属性Binding到BookEx集合上,下面修改ComboBox的DataTemplate:
此时已经可以实现多选了,但是当选择相应的条目后,在ComboBox的Text区域并不显示。下面来解决这个问题。实现方式是将选中的Book的Name属性集合Binding到ComboBox的Text属性上面。对ViewModel做一些改造,增加一个SelectedText属性,用来显示选中的条目Name集合
public ObservableCollection<BookEx> BookExs
{
get
{
if(_books == null)
{
_books = new ObservableCollection<BookEx>(); _books.CollectionChanged += (sender, e) =>
{
if(e.OldItems != null)
{
foreach (BookEx bookEx in e.OldItems)
{
bookEx.PropertyChanged -= ItemPropertyChanged;
}
} if(e.NewItems != null)
{
foreach (BookEx bookEx in e.NewItems)
{
bookEx.PropertyChanged += ItemPropertyChanged;
}
}
};
} return _books;
}
} private void ItemPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if(e.PropertyName == "IsChecked")
{
BookEx bookEx = sender as BookEx; if(bookEx != null)
{
IEnumerable<BookEx> bookExs = BookExs.Where(b => b.IsChecked == true); StringBuilder builder = new StringBuilder(); foreach (BookEx item in bookExs)
{
builder.Append(item.Book.Name + " ");
} SelectedText = builder == null ? string.Empty : builder.ToString();
}
}
}
最后一个注意点,修改ComboBox的IsEditable="True",只有这样才能接收Text的Binding。
<ComboBox Text="{Binding SelectedText}" IsEditable="True" ItemsSource="{Binding Path=BookExs}">
<ComboBox.ItemTemplate>
<DataTemplate DataType="{x:Type local:BookEx}">
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding IsChecked}" />
<TextBlock Text="{Binding Book.Name}" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
实现的效果如下:
就这样一个可以多选的ComboBox就实现了。代码点击这里下载。
感谢您的阅读,如果您有其他实现方式,欢迎在评论区域点评,谢谢~
WPF中实现多选ComboBox控件的更多相关文章
- WPF中不规则窗体与WindowsFormsHost控件的兼容问题完美解决方案
首先先得瑟一下,有关WPF中不规则窗体与WindowsFormsHost控件不兼容的问题,网上给出的解决方案不能满足所有的情况,是有特定条件的,比如 WPF中不规则窗体与WebBrowser控件的兼 ...
- WPF中不规则窗体与WebBrowser控件的兼容问题解决办法
原文:WPF中不规则窗体与WebBrowser控件的兼容问题解决办法 引言 这几天受委托开发一个网络电视项目,要求初步先使用内嵌网页形式实现视频播放和选单,以后再考虑将网页中的所有功能整合进桌面程序. ...
- WPF 中动态创建和删除控件
原文:WPF 中动态创建和删除控件 动态创建控件 1.容器控件.RegisterName("Name",要注册的控件) //注册控件 2.容器控件.FindName(" ...
- 封装:WPF中可以绑定的BindPassWord控件
原文:封装:WPF中可以绑定的BindPassWord控件 一.目的:本身自带的PassWord不支持绑定 二.Xaml部分 <UserControl x:Class="HeBianG ...
- WPF 中动态创建、删除控件,注册控件名字,根据名字查找控件
动态创建控件 1.容器控件.RegisterName("Name",要注册的控件) //注册控件 2.容器控件.FindName("Name") as 控 ...
- WPF中增加Month Calendar月历控件
XAML代码:(这里使用了codeproject.com网站上的一个Dll,你可以在这里下载它:http://www.codeproject.com/cs/miscctrl/MonthCalendar ...
- tkinter中checkbutton多选框控件和variable用法(六)
checkbutton控件 简单的实现多选: import tkinter wuya = tkinter.Tk() wuya.title("wuya") wuya.geometry ...
- 在WPF中的Canvas上实现控件的拖动、缩放
如题,项目中需要实现使用鼠标拖动.缩放一个矩形框,WPF中没有现成的,那就自己造一个轮子:) 造轮子前先看看Windows自带的画图工具中是怎样做的,如下图: 在被拖动的矩形框四周有9个小框,可以从不 ...
- WPF中Expander的用法和控件模板详解
一.Expander的用法 在WPF中,Expander是一个很实用的复合控件,可以很方便的实现下拉菜单和导航栏等功能.先介绍简单的用法,而后分析他的控件模板. <Window.Resource ...
随机推荐
- commons-logging 结合 log4j, 初始化生命周期 初探
-------commons-logging---------- Log log=LogFactory.getLog(clazz); LogFactory这是个抽象日志工厂,更像个工具? 通过线程上下 ...
- PVM的安装和编译PVM程序
最近刚开始学习并发编程,学习到了PVM这一块.关于在linux系统中PVM的安装,真是要我的命,繁琐死了,最关键是我对linux也是刚开始学,还在继续学习<鸟哥的linux私房菜>一书.好 ...
- SQLite的总结与在C#的使用
这几天接触了一下SQLite,算是有点收获吧,因此总结一下. SQLite简介: SQLite是用C语言编写的数据库引擎,可以运行在Linux.Windows.Mac平台上. SQLite安装简单,下 ...
- Educational Codeforces Round 21 A-E题题解
A题 ............太水就不说了,贴下代码 #include<string> #include<iostream> #include<cstring& ...
- 关于Lumen / Laravel .env 文件中的环境变量是如何生效的
.env 文件包含默认环境变量,我们还可自定义其他任何有效的变量,并可通过 调用 env() 或 $_SERVER 或 $_ENV 来获取该变量.那么env()是如何加载到这些变量的呢?在Lume ...
- 流畅python学习笔记:第十章:序列的修改,散列和切片
前面在介绍了类的很多内置方法,比如__add__,__eq__,这里继续介绍类的两个内置方法,这2个内置方法可以将一个类实例变成一个序列的形式.代码如下 class vector(object): ...
- Java的基本数据类型和运算
编码 ASCII--0~127 65-A 97-a 西欧码表---ISO-8859-1---0-255---1个字节 gb2312----0-65535---gbk---2个字节 Unicode编 ...
- 深入理解 JavaScript(一)
编写高质量 JavaScript 代码的基本要点 转载:http://wiki.jikexueyuan.com/project/javascript-depth-understanding/start ...
- vue路由跳转时判断用户是否登录功能
通过判断该用户是否登录过,如果没有登录则跳转到login登录路由,如果登录则正常跳转. 一丶首先在用户登录前后分别给出一个状态来标识此用户是否登录(建议用vuex): 简单用vuex表示一下,不会可以 ...
- jvm学习002 虚拟机类加载过程以及主动引用和被动引用
虚拟机把描述类的数据从class文件加载到内存,并对数据进行校验,转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制. 类从被加载到虚拟机内存中开始,到卸载出内存为 ...