C#-下拉多选

简介: 本例通过模板实现支持多选的下拉框,使用CheckBox自定义ComboBox项,并在选中时将内容拼接显示在输入框中。

如何让下拉项能够支持多选?

当用户勾选下拉项时,下拉框中显示勾选的内容,并用逗号隔开,这里使用模板实现,在Combobox.ItemTemplate中使用Checkbox,参考代码如下:

<ComboBox Width="100" 
          IsEditable="True" 
          IsReadOnly="True" 
          Text="{Binding ItemText}"
          ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedItem}">
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <CheckBox Content="{Binding Name}"
                      IsChecked="{Binding IsChecked,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
                      Width="{Binding ActualWidth,RelativeSource={RelativeSource AncestorType=ComboBox}}">
            </CheckBox>
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

如果你不设置CheckBox的宽度,这里点击到非CheckBox的区域的时候,ComboBox会显示选中的行,这显然不是我们想要的效果,简单的处理,即将ChecBox尽可能的占据ComboBoxItem的区域,所以我们在这里设置了它的宽度,并且将ComboBoxItem的Margin,Padding设置为0。

如何让选中的项都显示在下拉框中?

ComboBox的Text绑定了ItemText,IsChecked绑定了项的IsChecked属性,在属性改变时我们拼接ItemText的内容,参考代码如下:

private void Item_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
{
   
    if (e.PropertyName == "IsChecked")
    {
   
        string strItems = "";
        foreach(var item in Items)
        {
   
            if (item.IsChecked)
            {
   
                strItems += item.Name+",";
            }
        }
        ItemText = strItems.TrimEnd(',');
    }
}

image.png

完整参考代码

//mainwindow.xaml
<Window x:Class="ComboBoxTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ComboBoxTest"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.Resources>
        <Style TargetType="ComboBoxItem">
            <Setter Property="Margin" Value="0"></Setter>
            <Setter Property="Padding" Value="0"></Setter>
        </Style>
    </Window.Resources>
    <Grid>
        <WrapPanel>
            <ComboBox Width="100" 
                      IsEditable="True" 
                      IsReadOnly="True" 
                      Text="{Binding ItemText}"
                      ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedItem}">
                <ComboBox.ItemTemplate>
                    <DataTemplate>
                        <CheckBox Content="{Binding Name}"
                                  IsChecked="{Binding IsChecked,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
                                  Width="{Binding ActualWidth,RelativeSource={RelativeSource AncestorType=ComboBox}}">
                        </CheckBox>
                    </DataTemplate>
                </ComboBox.ItemTemplate>
            </ComboBox>
        </WrapPanel>
    </Grid>
</Window>
//mainwindow.xaml.cs
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using CommunityToolkit.Mvvm.ComponentModel;

namespace ComboBoxTest
{
   
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
   
        public MainWindow()
        {
   
            InitializeComponent();
            this.DataContext = new MainWindowViewModel();
        }
    }
    public class Item: ObservableObject
    {
   
        private string m_Name;
        public string Name
        {
   
            get {
    return m_Name; }
            set {
    SetProperty(ref m_Name, value); }
        }
        private bool m_IsChecked;
        public bool IsChecked
        {
   
            get
            {
   
                return m_IsChecked;
            }
            set
            {
   
                SetProperty(ref m_IsChecked, value);
            }
        }
    }
    public class MainWindowViewModel:ObservableObject
    {
   
        public MainWindowViewModel() 
        {
   
            Item item = new Item();
            item.Name = "123";
            item.PropertyChanged += Item_PropertyChanged;
            Items.Add(item);

            Item item1 = new Item();
            item1.Name = "456";
            item1.PropertyChanged += Item_PropertyChanged;
            Items.Add(item1);

            Item item2 = new Item();
            item2.Name = "789";
            item2.PropertyChanged += Item_PropertyChanged;
            Items.Add(item2);
        }

        private void Item_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
   
            if (e.PropertyName == "IsChecked")
            {
   
                string strItems = "";
                foreach(var item in Items)
                {
   
                    if (item.IsChecked)
                    {
   
                        strItems += item.Name+",";
                    }
                }
                ItemText = strItems.TrimEnd(',');
            }
        }

        private ObservableCollection<Item> m_Items = new ObservableCollection<Item>();
        public ObservableCollection<Item> Items
        {
   
            get
            {
   
                return m_Items;
            }
            set
            {
   
                SetProperty(ref m_Items,value);
            }
        }
        private string m_ItemText;
        public string ItemText
        {
   
            get
            {
   
                return m_ItemText;
            }
            set
            {
   
                SetProperty(ref m_ItemText,value);
            }
        }
    }
}
目录
相关文章
|
11月前
|
C#
C#-ListBox多选绑定
在WPF中,ListBox的SelectedItems属性为只读,无法直接绑定多选数据。本文通过定义一个附加属性实现双向绑定,利用依赖属性和事件监听同步选中项,从而解决该问题。
352 8
|
11月前
|
JSON 监控 BI
拼多多批量下单工具,拼多多买家批量下单软件,低价下单python框架分享
使用Selenium实现自动化操作流程多线程订单处理提升效率
|
11月前
|
人工智能 自然语言处理 API
构建可落地的企业AI Agent,背后隐藏着怎样的技术密码?
三桥君深入解析企业AI Agent技术架构,涵盖语音识别、意图理解、知识库协同、语音合成等核心模块,探讨如何实现业务闭环与高效人机交互,助力企业智能化升级。
475 6
|
11月前
|
数据采集 分布式计算 DataWorks
ODPS在某公共数据项目上的实践
本项目基于公共数据定义及ODPS与DataWorks技术,构建一体化智能化数据平台,涵盖数据目录、归集、治理、共享与开放六大目标。通过十大子系统实现全流程管理,强化数据安全与流通,提升业务效率与决策能力,助力数字化改革。
373 4
|
11月前
|
运维 Prometheus 安全
服务网格真香,但怎么优化才不翻车?
服务网格真香,但怎么优化才不翻车?
264 3
|
11月前
|
数据可视化 Java 数据库连接
Dataphin JDBC:助您实现数据权限的集中管理
Dataphin JDBC提供了统一访问Dataphin中数据的功能,助您实现数据权限的集中式管理。
460 3
|
11月前
|
存储 监控 安全
RFID让智慧工地管理更简便
RFID技术助力智慧工地管理,实现人员、材料、设备的高效管控与安全提升。通过智能识别与数据追踪,优化施工流程,保障工程进度与质量,推动建筑行业智能化发展。
|
12月前
|
人工智能 监控 安全
人人都是造梦者:AI时代的创意落地指南
有好想法因为"不会技术"而只能停留在脑海里?如果技术门槛不再是阻碍,你最想实现什么?在发现好想法后,如何落地自己的AI创意?这个过程可能需要哪些东西?本文手把手教你如何让自己的创意落地。
662 16
人人都是造梦者:AI时代的创意落地指南
|
11月前
|
存储 Java API
VMware Cloud Foundation 9.0 之 VCF Installer 的新增功能
VMware Cloud Foundation 9.0 之 VCF Installer 的新增功能
212 2
VMware Cloud Foundation 9.0 之 VCF Installer 的新增功能
|
11月前
|
SQL 存储 关系型数据库
MySQL功能模块探秘:数据库世界的奇妙之旅
]带你轻松愉快地探索MySQL 8.4.5的核心功能模块,从SQL引擎到存储引擎,从复制机制到插件系统,让你在欢声笑语中掌握数据库的精髓!
335 26