You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

搜索时如何保持CheckedListBox项的选中状态?

解决CheckedListBox搜索时选中状态丢失的问题

问题根源在于使用DataView.RowFilter过滤数据时,CheckedListBox的项会重新渲染,原有的选中状态是基于项的索引绑定的,过滤后项的索引发生变化,导致选中状态丢失。直接操作选中项集合时还可能因为数据源变更引发异常,正确的做法是通过唯一标识(Property_Id)保存和恢复选中状态,具体实现如下:

  1. 定义集合存储选中项的唯一ID
    在UserControl类中添加私有字段,用来持久化选中项的Property_Id:
private HashSet<int> _selectedPropertyIds = new HashSet<int>();
  1. 修改搜索文本变更事件,先保存选中ID再过滤,最后恢复选中状态
    更新Searchtext_TextChanged方法,在过滤前把当前选中项的Property_Id存入集合,过滤完成后遍历新的项集合,根据ID匹配恢复选中:
private void Searchtext_TextChanged(object sender, EventArgs e)
{
    if (checkedListBox1.DataSource is DataTable dt)
    {
        // 保存当前选中的Property_Id
        _selectedPropertyIds.Clear();
        foreach (int index in checkedListBox1.CheckedIndices)
        {
            if (checkedListBox1.Items[index] is DataRowView rowView)
            {
                int propertyId = Convert.ToInt32(rowView["Property_Id"]);
                _selectedPropertyIds.Add(propertyId);
            }
        }

        // 执行过滤逻辑
        var str = Searchtext.Text.Trim();
        dt.DefaultView.RowFilter = string.IsNullOrEmpty(str)
            ? null
            : $"Property_Name LIKE '%{str}%'";

        // 根据保存的ID恢复选中状态
        foreach (int index in Enumerable.Range(0, checkedListBox1.Items.Count))
        {
            if (checkedListBox1.Items[index] is DataRowView rowView)
            {
                int propertyId = Convert.ToInt32(rowView["Property_Id"]);
                checkedListBox1.SetItemChecked(index, _selectedPropertyIds.Contains(propertyId));
            }
        }
    }
}
  1. 可选:初始化加载时保留选中状态
    如果需要在控件初始化或重新加载数据后恢复之前的选中状态,可在LoadProperty方法末尾添加恢复逻辑:
private void LoadProperty()
{
    checkedListBox1.DisplayMember = "Property_Name";
    checkedListBox1.ValueMember = "Property_Id";
    checkedListBox1.DataSource = GetDataTable();

    // 恢复之前保存的选中状态
    foreach (int index in Enumerable.Range(0, checkedListBox1.Items.Count))
    {
        if (checkedListBox1.Items[index] is DataRowView rowView)
        {
            int propertyId = Convert.ToInt32(rowView["Property_Id"]);
            checkedListBox1.SetItemChecked(index, _selectedPropertyIds.Contains(propertyId));
        }
    }
}

通过以上修改,无论搜索过滤如何改变项的显示集合,都能通过唯一的Property_Id准确恢复用户之前的选中状态,避免索引变化导致的状态丢失和异常问题。

内容的提问来源于stack exchange,提问作者WM1

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 14:01:05