在ItemCheck事件之后清除CheckedListBox

问题描述 投票:1回答:2

在我用C#编写的Windows窗体项目中,我尝试在检查完最后一个项目后清除CheckedListBox。

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

在这个例子中,在我检查最后一个项目之后,程序将抛出NullReferenceException。

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

提前致谢!

c# .net winforms checkedlistbox
2个回答
2
投票

在更新项目的检查状态后更改代码以运行逻辑:

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

根据documentations,默认情况下,当ItemCheck事件发生时,项目的检查状态直到ItemCheck事件发生后才更新。这意味着它在运行事件处理程序中的代码后尝试更新项的检查状态。因此,在您的代码中,它会在项目集合中删除项目后尝试更新项目检查状态,这就是发生异常的原因。您可以在控件的source code中查看堆栈跟踪中发生的情况。

在上面的代码中,使用BeginInvoke我们在更新检查状态后延迟运行代码。你可以在this post上阅读更多相关信息。


1
投票

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

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

不同的是时间,qazxsw poi是早期触发的,当时你无法清除这些物品,并且qazxsw poi被触发的时间要晚得多。

© www.soinside.com 2019 - 2024. All rights reserved.