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!
CheckedIndices
. The count isn't updated at the time when we check the count.. – Gatlin