イベントのドキュメントには、次のように記載されています。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
、新しいスレッド形式のスレッド プールを呼び出しました。
これに対する別の解決策として、メッセージを登録して手動でメッセージ キューに投稿することもできますが、それにはさらに多くのコードが必要になります。