事件的文档CheckedListBox.ItemCheck
指出:
直到 ItemCheck 事件发生后,检查状态才会更新。
所以当事件被调用时,CheckedIndices.Count
还没有更新。为了克服这个问题,您必须继承CheckedListBox
该类并在事件之后触发一个新事件CheckedListBox.ItemCheck
:
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);
}));
}
不,您有一个ItemCheckedChanged
可以订阅的活动。
实际上没有必要子类化。这可以在表单本身中完成,但这更干净。
它是如何工作的?
该ItemCheck
事件在方法内部调用SetItemCheckState
。此方法在调用事件 ( )后更改项目的检查状态。OnItemCheck
调用SetItemCheck
也是传递到应用程序消息队列的 Windows 消息的结果。我们希望在处理完这条消息后触发我们的消息,所以我们必须向队列中发布一条新消息,以便在这条消息之后处理我们的消息。该BeginInvoke
方法实际上将消息发布到消息队列中,但前提是从另一个线程调用。这就是为什么我调用BeginInvoke
了一个新的线程形式的线程池。
另一个解决方案是注册一条消息并手动将其发布到消息队列,但这将是更多的代码!