检查项目后会触发哪个CheckedListBox事件?

hul*_*ist 83 c# checkedlistbox winforms

我有一个CheckedListBox,我想一个项目被检查我想要一个事件,以便我可以使用具有新状态的CheckedItems.

由于在CheckedItems更新之前触发了ItemChecked,因此它不会开箱即用.

更新CheckedItems时,我可以使用哪种方法或事件来通知?

Bra*_*mir 78

ItemCheck如果还检查正在单击的项目的新状态,则可以使用该事件.这在事件args中可用,如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)
        {
            ...
        }
    }
Run Code Online (Sandbox Code Playgroud)

作为另一个示例,在(未)检查此项目后确定集合是否为空:

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
        ...
}
Run Code Online (Sandbox Code Playgroud)

  • 问题是在处理检查之前触发了ItemCheck事件.您的解决方案将涉及保留您自己的列表,基本上复制标准代码.Dunc的第一个建议(在ItemCheck上延迟执行)是对phq问题最干净的答案,因为它不需要任何额外的处理. (8认同)
  • 在每个的第一个中,我们可能需要添加一个if条件..`if not item = checkedListBox1.Items [e.Index] .ToString()` (3认同)

Dun*_*unc 29

这里有很多相关的StackOverflow帖子......除了Branimir的解决方案,还有两个更简单的方法:

在ItemCheck上延迟执行(也在这里):

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

使用MouseUp事件:

    void checkedListBox1_MouseUp(object sender, MouseEventArgs e)
    {
        Console.WriteLine(checkedListBox1.SelectedItems.Count);
    }
Run Code Online (Sandbox Code Playgroud)

我更喜欢第一种选择,因为第二种选择会导致误报(即经常射击).

  • 第二种方法也会错过通过键盘检查或取消选中的项目. (11认同)
  • BeginInvoke 正是我所需要的,因为我的事件实际上是调用一个接口,它不知道它正在处理什么样的控件。接受的答案仅适用于逻辑可以在事件处理程序中执行或直接从事件处理程序调用的情况。对我来说情况并非如此。感谢这个很棒但简单的解决方案。 (2认同)

小智 22

我试过这个并且它有效:

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();        
}
Run Code Online (Sandbox Code Playgroud)

  • 这个!......应该是正确答案,最不幸的是.这是一个荒谬的黑客行为,因为M $的某个人忘了实施`ItemChecked`事件,没有人说过它不存在. (8认同)

dii*_*eep 10

衍生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);
}
Run Code Online (Sandbox Code Playgroud)


Iai*_*ard 5

尽管并不理想,但您可以使用传递给ItemCheck事件的参数来计算 CheckedItems。如果您在 MSDN 上查看此示例,您可以确定新更改的项目是否已选中或未选中,这使您处于合适的位置来处理这些项目。

您甚至可以创建一个在检查项目后触发的新事件,如果您愿意,这将准确地为您提供所需的内容。


Ant*_*ite 5

经过一些测试,我可以看到事件 SelectedIndexChanged 在事件 ItemCheck 之后触发。保持属性 CheckOnClick True

最佳编码

  • 当您使用空格键更改检查状态时,它不会触发。使用这个是错误的。 (2认同)