在 CheckedListBox C# 中搜索项目

问题描述 投票:0回答:1

我有一个 CheckedListBox 和一个文本框。这里的目标是创建一个可搜索的 CheckedListBox。当我在 TextBox 中输入内容时,我必须过滤 CheckedListBox 中的项目。 我编写了下面的代码来执行此操作,但是每次输入文本时,CheckedListBox 项目都会被清除,并且会出现新的过滤项目列表。这段代码的问题是过滤工作正常,但选中的项目每次都会被重置。

public partial class Form1 : Form
{
    string[] elArray = {"Not Applicable" , "Aberdeen - Delivered" , "Belfast - Delivered" , "Birmingham - Delivered" , "Bournemouth - Delivered" , "Bradford - Delivered" , "Bristol - Delivered" , "Cambridge - Delivered" , "Canterbury - Delivered" , "OTHERS TO DE ADDED ..."};
    public Form1()
    {
        InitializeComponent();
        foreach (string elData in elArray)
        {
            resultBoxList.Items.Add(elData);
        }
    }

    private void searchBox_TextChanged(object sender, EventArgs e)
    {
        resultBoxList.Items.Clear();
        string[] resultArray = { };
        foreach (string res in elArray)
        {
            if (res.Contains(searchBox.Text))
            {
                resultBoxList.Items.Add(res);
            }
        }
        foreach (string resData in resultArray)
        {
            resultBoxList.Items.Add(resData);
        }
    }
}

enter image description here enter image description here

c# winforms checkedlistbox
1个回答
5
投票

您有两个问题需要解决:

  1. 应用过滤器并保留列表项。
  2. 保留项目的选中状态。

您可以通过使用 DataTable 作为列表项及其选中状态的数据源,并将其默认的 DataView 绑定到 CheckedListBox.DataSource 属性来实现这一点。

注意
DataSource
控件的
DisplayMember
ValueMember
CheckedListBox
属性处于隐藏状态。它们不会显示在“属性”窗口中,也不会显示在 IntelliSense 中。

这些属性是隐藏的,尤其是
DataSource
,因为它将
DataManager
的功能委托给基类,
ListBox
不知道关于。因此不处理复选框的状态(即,它不会重写
OnDataSourceChanged()
方法来生成自定义或专门的行为。

首先,创建数据表,添加项目并填充控件。

public Form1()
{
    InitializeComponent();

    var elArray = new[]
    {
        "Not Applicable",
        "Aberdeen - Delivered",
        "Belfast - Delivered",
        "Birmingham - Delivered",
        "Bournemouth - Delivered",
        "Bradford - Delivered",
        "Bristol - Delivered",
        "Cambridge - Delivered",
        "Canterbury - Delivered",
        "OTHERS TO DE ADDED ..."
    };
    var dt = new DataTable();

    dt.Columns.Add("Item", typeof(string));
    dt.Columns.Add("Checked", typeof(bool));

    foreach (var item in elArray) dt.Rows.Add(item, false);

    dt.AcceptChanges();

    resultBoxList.DataSource = dt.DefaultView;
    resultBoxList.DisplayMember = "Item";
    resultBoxList.ValueMember = "Item";

    // If not already done by the designer...
    resultBoxList.ItemCheck += resultBoxList_ItemCheck;
}

其次,处理 ItemCheck 事件以更新数据源中的选中状态。

private void resultBoxList_ItemCheck(object sender, ItemCheckEventArgs e)
{
    var dv = resultBoxList.DataSource as DataView;
    var drv = dv[e.Index];
    drv["Checked"] = e.NewValue == CheckState.Checked ? true : false;
}

最后,在

TextChanged
事件中,解决上述问题:

  1. 设置DataView.RowFilter以应用/删除过滤器。在您的情况下,您需要使用 LIKE 运算符。有关更多模式和详细信息,请参阅引用的链接。
  2. 从数据源恢复选中的状态。
private void searchBox_TextChanged(object sender, EventArgs e)
{
    var dv = resultBoxList.DataSource as DataView;
    var filter = searchBox.Text.Trim().Length > 0
        ? $"Item LIKE '{searchBox.Text}*'"
        : null;

    dv.RowFilter = filter;

    for (var i = 0; i < resultBoxList.Items.Count; i++)
    {
        var drv = resultBoxList.Items[i] as DataRowView;
        var chk = Convert.ToBoolean(drv["Checked"]);
        resultBoxList.SetItemChecked(i, chk);
    }
}

SOQ66080248

© www.soinside.com 2019 - 2024. All rights reserved.