在 ItemCheck 事件后清除 CheckedListBox

Clear CheckedListBox after ItemCheck Event

在我用 C# 编写的 windows 表单项目中,我尝试在选中最后一个项目后清除 CheckedListBox。

private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e)
{
    if (checkedListBox1.CheckedItems.Count + 1 == checkedListBox1.Items.Count)
    {
        checkedListBox1.Items.Clear();
    }
}

在此示例中,程序将在我检查最后一项后抛出 NullReferenceException。

有人可以解释为什么会发生这种情况以及我该如何处理吗?

提前致谢!

这是因为在您从checklistbox中清除项目后,有一些内部调用(System.Windows.Forms.CheckedListBox.CheckedItemCollection.SetCheckedState)在稍后调用并且仍然对项目进行操作。所以它抛出 NullReferenceException.

如果您改为注册 SelectedIndexChanged 事件,则可以清除项目而不会出现此问题。

不同的是时间,ItemCheck触发的早,那个时候不能清空物品,SelectedIndexChanged触发的晚

将您的代码更改为运行项目检查状态更新后的逻辑:

private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e)
{
    checkedListBox1.BeginInvoke(new Action(() =>
    {
        if (checkedListBox1.CheckedItems.Count == checkedListBox1.Items.Count)
        {
            checkedListBox1.Items.Clear();
        }
    }));
}

根据documentations, by default, when the ItemCheck event raises, the check state of the item is not updated until after the ItemCheck event occurs. It means it tries to update the check state of the item after running the code that you have in the event handler. As a result in your code, it tries to update item check state after the item removed from items collection and that's why an exception happens. You can see what happens in stack trace, also in source code的对照。

在上面的代码中,使用 BeginInvoke 我们在检查状态更新后延迟 运行ning 代码。您可以在 this post.

中阅读更多相关信息