web-dev-qa-db-ja.com

アイテムのチェック後にトリガーされるCheckedListBoxイベントはどれですか?

イベントが必要なCheckedListBoxがありますafter新しい状態でCheckedItemsを使用できるように項目がチェックされます。

ItemCheckedはCheckedItemsが更新される前に起動されるため、そのままでは機能しません。

CheckedItemsが更新されたときに通知を受けるには、どのようなメソッドまたはイベントを使用できますか?

81
hultqvist

クリックされているアイテムの新しい状態も確認する場合は、ItemCheckイベントを使用できます。これは、イベント引数でe.NewValueNewValueがチェックされている場合は、ロジックに適切なコレクションとともに現在のアイテムを含めます。

    private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e)
    {                     
        List<string> checkedItems = new List<string>();
        foreach (var item in checkedListBox1.CheckedItems)
            checkedItems.Add(item.ToString());

        if (e.NewValue == CheckState.Checked)
            checkedItems.Add(checkedListBox1.Items[e.Index].ToString());
        else
            checkedItems.Remove(checkedListBox1.Items[e.Index].ToString());

        foreach (string item in checkedItems)
        {
            ...
        }
    }

別の例として、このアイテムがチェックされた後にコレクションが空になるかどうかを判断するには:

private void ListProjects_ItemCheck(object sender, ItemCheckEventArgs args)
{
    if (ListProjects.CheckedItems.Count == 1 && args.NewValue == CheckState.Unchecked)
        // The collection is about to be emptied: there's just one item checked, and it's being unchecked at this moment
        ...
    else
        // The collection will not be empty once this click is handled
        ...
}
78
Branimir

関連するStackOverflowの投稿が多数あります... Branimir's ソリューションと同様に、さらに2つの簡単なものがあります。

ItemCheckの遅延実行 (また ここ ):

    void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e)
    {
        this.BeginInvoke((MethodInvoker) (
            () => Console.WriteLine(checkedListBox1.SelectedItems.Count)));
    }

MouseUpイベントを使用

    void checkedListBox1_MouseUp(object sender, MouseEventArgs e)
    {
        Console.WriteLine(checkedListBox1.SelectedItems.Count);
    }

2番目のオプションは誤検知(つまり、頻繁に起動する)になるため、最初のオプションを選択します。

28
Dunc

私はこれを試してみましたが、うまくいきました:

private void clbOrg_ItemCheck(object sender, ItemCheckEventArgs e)
{
    CheckedListBox clb = (CheckedListBox)sender;
    // Switch off event handler
    clb.ItemCheck -= clbOrg_ItemCheck;
    clb.SetItemCheckState(e.Index, e.NewValue);
    // Switch on event handler
    clb.ItemCheck += clbOrg_ItemCheck;

    // Now you can go further
    CallExternalRoutine();        
}
20
softburger

CheckedListBoxから派生して実装する

/// <summary>
/// Raises the <see cref="E:System.Windows.Forms.CheckedListBox.ItemCheck"/> event.
/// </summary>
/// <param name="ice">An <see cref="T:System.Windows.Forms.ItemCheckEventArgs"/> that contains the event data.
///                 </param>
protected override void OnItemCheck(ItemCheckEventArgs e)
{           
    base.OnItemCheck(e);

    EventHandler handler = AfterItemCheck;
    if (handler != null)
    {
        Delegate[] invocationList = AfterItemCheck.GetInvocationList();
        foreach (var receiver in invocationList)
        {
            AfterItemCheck -= (EventHandler) receiver;
        }

        SetItemCheckState(e.Index, e.NewValue);

        foreach (var receiver in invocationList)
        {
            AfterItemCheck += (EventHandler) receiver;
        }
    }
    OnAfterItemCheck(EventArgs.Empty);
}

public event EventHandler AfterItemCheck;

public void OnAfterItemCheck(EventArgs e)
{
    EventHandler handler = AfterItemCheck;
    if (handler != null)
        handler(this, e);
}
9
diimdeep

理想的ではありませんが、ItemCheckイベントに渡される引数を使用してCheckedItemsを計算できます。これを見ると MSDNの例 で、新しく変更されたアイテムがチェックされているかチェックされていないかを判断できます。

アイテムがチェックされた後に起動する新しいイベントを作成することもできます。これにより、必要に応じて必要なものを正確に提供できます。

4
Iain Ward

いくつかのテストの後、イベントItemCheckの後にイベントSelectedIndexChangedがトリガーされることがわかりました。プロパティCheckOnClickをTrueのままにします

最高のコーディング

4
Antonio Leite

これは動作しますが、どれだけエレガントかはわかりません!

Private Sub chkFilters_Changed(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkFilters.ItemCheck
    Static Updating As Boolean
    If Updating Then Exit Sub
    Updating = True

    Dim cmbBox As CheckedListBox = sender
    Dim Item As ItemCheckEventArgs = e

    If Item.NewValue = CheckState.Checked Then
        cmbBox.SetItemChecked(Item.Index, True)
    Else
        cmbBox.SetItemChecked(Item.Index, False)
    End If

    'Do something with the updated checked box
    Call LoadListData(Me, False)

    Updating = False
End Sub
2
FireMatt

ItemCheckからの引数を保持したいが、モデルが変更された後に通知されると仮定すると、次のようになります。

CheckedListBox ctrl = new CheckedListBox();
ctrl.ItemCheck += (s, e) => BeginInvoke((MethodInvoker)(() => CheckedItemsChanged(s, e)));

CheckedItemsChangedは次のとおりです。

private void CheckedItemsChanged(object sender, EventArgs e)
{
    DoYourThing();
}
1
Slion

これが当てはまるかどうかはわかりませんが、チェックリストボックスを使用して結果をフィルタリングしたかったのです。したがって、ユーザーがアイテムをチェックしたりチェックを外したりすると、リストにアイテムの表示/非表示が必要になりました。

この投稿につながったいくつかの問題がありました。特別なことをせずにどうやってやったかを共有したかっただけです。

注:CheckOnClick = trueがありますが、おそらくそれがなくても動作します

私が使用するイベントは「SelectedIndexChanged」です

私が使用する列挙体は「。CheckedItems

これにより、私たちが期待する結果が得られます。とても簡単になりました....

private void clb1_SelectedIndexChanged(object sender, EventArgs e)
{
   // This just spits out what is selected for testing
   foreach (string strChoice in clb1.CheckedItems)
   {
      listBox1.Items.Add(strChoice);
   }

   //Something more like what I'm actually doing
   foreach (object myRecord in myRecords)
   {
        if (clb1.CheckItems.Contains(myRecord["fieldname"])
        {
            //Display this record
        }
   }

}
1
da_jokker

通常の動作では、1つのアイテムをチェックすると、イベントハンドラーが発生する前にアイテムのチェック状態が変更されます。ただし、CheckListBoxの動作は異なります。イベントハンドラーは、アイテムのチェック状態が変化する前に発生するため、ジョブを修正するのが難しくなります。

私の意見では、この問題を解決するには、イベントハンドラを延期する必要があります。

private void _clb_ItemCheck(object sender, ItemCheckEventArgs e) {
 // Defer event handler execution
 Task.Factory.StartNew(() => {
     Thread.Sleep(1000);
     // Do your job at here
 })
 .ContinueWith(t => {
     // Then update GUI at here
 },TaskScheduler.FromCurrentSynchronizationContext());}
0
Thinh Vu

この問題を解決するためにタイマーを使用します。 ItemCheckイベントを介してタイマーを有効にします。タイマーのティックイベントでアクションを実行します。

これは、アイテムがマウスクリックでチェックされるか、スペースバーを押すことでチェックされるかに関係なく機能します。チェックされた(またはチェックされていない)アイテムは常に選択されたアイテムであるという事実を利用します。

タイマーの間隔は1に設定できます。Tickイベントが発生するまでに、新しいCheckedステータスが設定されます。

このVB.NETコードは概念を示しています。使用できる多くのバリエーションがあります。タイマーの間隔を増やして、ユーザーがアクションを実行する前にいくつかのアイテムのチェック状態を変更できるようにすることができます。次に、Tickイベントで、List内のすべてのアイテムのシーケンシャルパスを作成するか、CheckedItemsコレクションを使用して適切なアクションを実行します。

そのため、最初にItemCheckイベントでタイマーを無効にします。無効にしてから有効にすると、間隔期間が再開します。

Private Sub ckl_ItemCheck(ByVal sender As Object, _
                          ByVal e As System.Windows.Forms.ItemCheckEventArgs) _
    Handles ckl.ItemCheck

tmr.Enabled = False
tmr.Enabled = True

End Sub


Private Sub tmr_Tick(ByVal sender As System.Object, _
                     ByVal e As System.EventArgs) _
    Handles tmr.Tick

tmr.Enabled = False
Debug.Write(ckl.SelectedIndex)
Debug.Write(": ")
Debug.WriteLine(ckl.GetItemChecked(ckl.SelectedIndex).ToString)

End Sub
0
Bob Ashcraft