How to track checks in checkedListBox C#?
Asked Answered
M

3

7

I try to display the number of checked items in the checkedListBox: checkedListBox1.CheckedIndices.Count But how can i update my count, if i want to display it on label? I tried to write all in the ItemCheck event:

private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e)
    {            
        label1.Text= checkedListBox1.CheckedIndices.Count;
    }

But the count increases even if i uncheck the item :( I'd appreciate any help!

Moonstone answered 9/3, 2013 at 11:35 Comment(0)
M
1

Just add one or subtract one depending on the e.NewValue==CheckState.Checked

Masson answered 9/3, 2013 at 11:45 Comment(5)
It doesn't give an error, but it doesn't work either... Same behavior as with CheckedIndices. The count isn't updated at the time when we check the count..Gatlin
Just add one or subtract one depending on the e.NewValue==CheckState.Checked.Masson
thank you, it works! if (e.NewValue == CheckState.Checked) checks++; else if (e.NewValue == CheckState.Unchecked) checks--;Moonstone
Great! Simple is best! But the answer is in the comments, not the answer itself! Please edit the answer and put the correct solution.Shela
Fixing the answer itself, because as it currently stands it doesn't answer the question at all.Gatlin
S
3

The documentation for CheckedListBox.ItemCheck event states that:

The check state is not updated until after the ItemCheck event occurs.

so when the event is called, the CheckedIndices.Count is not yet updated. To overcome this, you have to subclass the CheckedListBox class and fire a new event after the CheckedListBox.ItemCheck event:

public class MyCheckedListBox : CheckedListBox
{
    public event ItemCheckEventHandler ItemCheckedChanged;
    protected virtual void OnItemCheckedChanged(ItemCheckEventArgs ice)
    {
        var h = ItemCheckedChanged;
        if (h != null)
            h(this, ice);
    }

    protected override void OnItemCheck(ItemCheckEventArgs ice)
    {
        base.OnItemCheck(ice);

        ThreadPool.QueueUserWorkItem(new WaitCallback((state) =>
            {
                this.BeginInvoke(new Action<ItemCheckEventArgs>(OnItemCheckedChanged), ice);
            }));
    }

No you have a ItemCheckedChanged event that you can subscribe to.

Actually there is no need to subclass. This can be done in the form itself, but this is cleaner.

How does it work?

The ItemCheck event is called inside the SetItemCheckState method. This method changes the check state of the item after calling the event (OnItemCheck). Also calling SetItemCheck is a consequence of a windows message that is passed to the message queue of the application. We want our message to be fired after this message is processed, so we have to post a new message into the queue, so that our message is processed after this message. The BeginInvoke method actually posts a message into the message queue, but only if called from another thread. That's why I called BeginInvoke in a new thread form thread pool.

Another solution to this could be registering a message and manually posting it to the message queue, but that would be a lot more code!

Shela answered 9/3, 2013 at 11:54 Comment(0)
M
1

Just add one or subtract one depending on the e.NewValue==CheckState.Checked

Masson answered 9/3, 2013 at 11:45 Comment(5)
It doesn't give an error, but it doesn't work either... Same behavior as with CheckedIndices. The count isn't updated at the time when we check the count..Gatlin
Just add one or subtract one depending on the e.NewValue==CheckState.Checked.Masson
thank you, it works! if (e.NewValue == CheckState.Checked) checks++; else if (e.NewValue == CheckState.Unchecked) checks--;Moonstone
Great! Simple is best! But the answer is in the comments, not the answer itself! Please edit the answer and put the correct solution.Shela
Fixing the answer itself, because as it currently stands it doesn't answer the question at all.Gatlin
R
0

Rather do the following:

int checkedcount = 0;
foreach(var item in checkedListBox1.CheckedItems){
   if(checkedListBox1.GetItemCheckState(checkedListBox1.Items.IndexOf(item) == System.Windows.Forms.CheckState.Checked)
      checkedcount++;
}

For further reference look here.

Rubel answered 9/3, 2013 at 11:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.