Search code examples
c#winformsdata-bindingcheckedlistbox

Updates in the DataSource reset CheckedListBox checkboxes


I have a CheckedListBox, binded to a BindingList:

private BindingList<string> list = new BindingList<string>();
public MyForm()
{
    InitializeComponent();

    list.Add("A");
    list.Add("B");
    list.Add("C");
    list.Add("D");

    checkedListBox.DataSource = collection;
}

When a certain button is clicked the list is updated:

private void Button_Click(object sender, EventArgs e)
{
    list.Insert(0, "Hello!");
}

And it works fine, the CheckedListBox is updated. However, when some of the items are checked, clicking the button not only updates the list but reset all the items to be unchecked. How can I fix that?

Thanks!


Solution

  • You need to track check-state yourself.

    As an option, you can create a model class for items containing text and check state. Then in ItemCheck event of the control, set check state value of the item model. Also in ListChenged event of your BindingList<T> refresh check-state of items.

    Example

    Create CheckedListBoxItem class:

    public class CheckedListBoxItem
    {
        public CheckedListBoxItem(string text)
        {
            Text = text;
        }
        public string Text { get; set; }
        public CheckState CheckState { get; set; }
        public override string ToString()
        {
            return Text;
        }
    }
    

    Setup the CheckedListBox like this:

    private BindingList<CheckedListBoxItem> list = new BindingList<CheckedListBoxItem>();
    private void Form1_Load(object sender, EventArgs e)
    {
        list.Add(new CheckedListBoxItem("A"));
        list.Add(new CheckedListBoxItem("B"));
        list.Add(new CheckedListBoxItem("C"));
        list.Add(new CheckedListBoxItem("D"));
        checkedListBox1.DataSource = list;
        checkedListBox1.ItemCheck += CheckedListBox1_ItemCheck;
        list.ListChanged += List_ListChanged;
    }
    private void CheckedListBox1_ItemCheck(object sender, ItemCheckEventArgs e)
    {
        ((CheckedListBoxItem)checkedListBox1.Items[e.Index]).CheckState = e.NewValue;
    }
    private void List_ListChanged(object sender, ListChangedEventArgs e)
    {
        for (var i = 0; i < checkedListBox1.Items.Count; i++)
        {
            checkedListBox1.SetItemCheckState(i,
                ((CheckedListBoxItem)checkedListBox1.Items[i]).CheckState);
        }
    }