• 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就实现了。代码点击这里下载。

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

  • 相关阅读:
    Codeforces Round #443 (Div. 2)ABC
    Codeforces Round #442 (Div. 2) ABC
    Wannafly挑战赛2 Cut
    热爱工作的蒜蒜
    Codeforces Round #441 (Div. 2) (ABC)
    Codeforces Round #440 (Div. 2)(ABC)
    Codeforces Round #439 (Div. 2)(ABC)
    sphinx 分词搭建手册
    [转]Chrome 控制台console的用法
    shell脚本复制文件夹内容到另外的文件夹,如果存在则自动备份
  • 原文地址:https://www.cnblogs.com/yang-fei/p/7364034.html
Copyright © 2020-2023  润新知