How to track checks in checkedListBox C#?

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!


只需添加一个或减去一个取决于e.NewValue==CheckState.Checked


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!


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.

链接地址: http://www.djcxy.com/p/69912.html

上一篇: 如何将H.264 NAL单元提供给Android MediaCodec进行解码?

下一篇: 如何跟踪checkedListBox C#中的检查?