您的位置:首页 > 其它

WPF中实现多选ComboBox控件

2017-08-15 11:13 459 查看
在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就实现了。代码点击这里下载。

感谢您的阅读,如果您有其他实现方式,欢迎在评论区域点评,谢谢~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: