[c#] 항목을 확인한 후 어떤 CheckedListBox 이벤트가 트리거됩니까?

새 상태에서 CheckedItems를 사용할 수 있도록 항목을 확인한 이벤트를 원하는 CheckedListBox가 있습니다.

CheckedItems가 업데이트되기 전에 ItemChecked가 실행되기 때문에 즉시 작동하지 않습니다.

CheckedItems가 업데이트 될 때 알림을 받으려면 어떤 종류의 메서드 또는 이벤트를 사용할 수 있습니까?



답변

ItemCheck클릭되는 항목의 새로운 상태를 확인하면 이벤트 를 사용할 수 있습니다 . 이벤트 인수에서 e.NewValue. 경우에 NewValue선택되어, 당신의 논리에 적절한 컬렉션과 함께 현재 항목을 포함한다 :

    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)
        {
            ...
        }
    }

또 다른 예로,이 항목을 (un-) 체크 한 후 컬렉션이 비어 있는지 확인하려면 :

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
        ...
}


답변

이것에 관한 많은 관련 StackOverflow 게시물이 있습니다 … Branimir의 솔루션 뿐만 아니라 다음 두 가지 더 간단한 것들이 있습니다.

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);
    }

첫 번째 옵션을 선호합니다. 두 번째 옵션은 오 탐지 (예 : 너무 자주 실행 됨)를 초래하기 때문입니다.


답변

나는 이것을 시도했고 효과가 있었다.

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();
}


답변

파생 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);
}


답변

이상적이지는 않지만 ItemCheck이벤트 로 전달되는 인수를 사용하여 CheckedItems를 계산할 수 있습니다 . MSDN 에서이 예제 를 보면 새로 변경된 항목이 선택되었는지 여부를 확인할 수 있으므로 항목 작업에 적합한 위치에있게됩니다.

항목이 확인 된 후 실행되는 새 이벤트를 생성하여 원하는 경우 원하는 것을 정확하게 제공 할 수도 있습니다.


답변

몇 가지 테스트 후 ItemCheck 이벤트 후에 SelectedIndexChanged 이벤트가 트리거되는 것을 볼 수 있습니다. 속성 CheckOnClick True 유지

최고의 코딩


답변

이것은 작동하지만 얼마나 우아한 지 확실하지 않습니다!

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