使CheckedListBox在Filter之后记住CheckedItems

时间:2015-11-03 16:49:39

标签: c# .net checkedlistbox listboxitems

尝试让CheckedListBox记住检查过的商品时遇到问题。在此计划中,我首次将DataTable中的项目加载到CheckedListBox,但在指定过滤器后,CheckedListBox会忘记所有已检查的项目。 所以问题是如何让它在获得应用后记住被检查的项目?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace AppNumber302
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        DataTable dt = new DataTable();

        private void Form1_Load(object sender, EventArgs e)
        {
            dt.Columns.Add("id");
            dt.Columns.Add("name");
            dt.Columns.Add("checked");

            dt.Rows.Add(10, "azer1", true);
            dt.Rows.Add(10, "azer2", true);
            dt.Rows.Add(10, "azer3", false);
            dt.Rows.Add(10, "azer4", false);

            checkedListBox1.DataSource = dt;
            checkedListBox1.DisplayMember = "name";
            checkedListBox1.ValueMember = "id";

            PerformCheck();
        }

        private void PerformCheck()
        {
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                DataRow drv = dt.Rows[i];
                bool stat = bool.Parse(drv[2].ToString());
                checkedListBox1.SetItemChecked(i, stat);
            }
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            try
            {
                DataRow[] dr = dt.Select("name LIKE '%" + textBox1.Text + "%'");
                DataTable tmp = dr.CopyToDataTable();
                checkedListBox1.DataSource = tmp;
                checkedListBox1.ValueMember = "id";
                checkedListBox1.DisplayMember = "name";
            }
            catch
            {
                checkedListBox1.DataSource = new DataTable();
            }
        }
    }
}

2 个答案:

答案 0 :(得分:0)

您正在重新绑定复选框列表(当您设置DataSource属性时)。因此,您之前在PerformCheck中所做的工作已经消失。一个简单的选择是在TextChanged处理程序中再次调用该方法。

答案 1 :(得分:0)

我一直在寻找类似问题的解决方案,最后我自己解决了,我知道这个帖子已经过时但我希望这可以帮助别人。

您可以创建一个列表来保存已选中的项目,以便在重新绑定时再次检查它们。 我将从我的代码中向您展示一个示例

List<object> checkedItems = new List<object>(); //List to save checked items
object[] checkListBoxItems = new object[]       //CheckedListBox items
{
"item1","item2","item3","item4","item5"
}
//Method called when item is checked in checkedListBox
private void CheckedListBox1_ItemCheck(object sender, ItemCheckEventArgs e)
    {
        if(e.NewValue == CheckState.Checked)
        {
            //If item is checked and not already on list, we add it to de list
            //With this filter we prevent adding the same item multiple times on rebind
            if (!checkedItems.Contains(checkedListBox1.Items[e.Index]))
            {
                checkedItems.Add(checkedListBox1.Items[e.Index]);
            }
        } 
        else
        {
            //If not checked, we remove it from list
            checkedItems.Remove(checkedListBox1.Items[e.Index]);
        }
    }

private void TextBox1_TextChanged(object sender, EventArgs e)
    {
        //Start update of checkedlistbox and clear items to refill
        checkedListBox1.BeginUpdate();
        checkedListBox1.Items.Clear();
        //If there is any text on the filter field
        if (!string.IsNullOrEmpty(textBox1.Text))
        {   
            //We check every item on our original item list (object array)
            foreach(object item in checkListBoxItems)
            {
                //Check if string in textfield matches item (case sensitive) 
                //and adds it to checkedListBox. At this point we should see the item
                if (item.ToString().Contains(textBox1.Text))
                {
                    checkedListBox1.Items.Add(item);
                }
            }
        }
        else
        {
            //If filter string is empty, we add the whole array of items to the list
            checkedListBox1.Items.AddRange(checkListBoxItems);
        }
        //Now checkedListBox is filled with the filtered(or not) items, its time
        //to check if they where checked previously and check them in the new list
        if(checkedClients.Count > 0)
        {
            foreach (object item in checkedListBoxItems)
            {
                if (checkedItems.Contains(item))
                {
                    //If item is shown in the list atm (otherwise it will crash)
                    if(checkedListBox1.Items.Contains(item)
                    {
                         checkedListBox1.SetItemChecked(checkedListBox1.Items.IndexOf(item), true);
                    }

                }
            }
        }

        checkedListBox1.EndUpdate();
    }