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就实现了。代码点击这里下载。
感谢您的阅读,如果您有其他实现方式,欢迎在评论区域点评,谢谢~
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。