在我用C#编写的Windows窗体项目中,我尝试在检查完最后一个项目后清除CheckedListBox。
private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e)
{
if (checkedListBox1.CheckedItems.Count + 1 == checkedListBox1.Items.Count)
{
checkedListBox1.Items.Clear();
}
}
在这个例子中,在我检查最后一个项目之后,程序将抛出NullReferenceException。
有人可以解释为什么会发生这种情况以及我如何处理这个问题?
提前致谢!
在更新项目的检查状态后更改代码以运行逻辑:
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上阅读更多相关信息。
这是因为在你清除checklistbox
中的项目之后,会有一些内部调用(System.Windows.Forms.CheckedListBox.CheckedItemCollection.SetCheckedState
)稍后调用并仍然对这些项目进行操作。所以它抛出了NullReferenceException
。
如果您注册了SelectedIndexChanged
事件,则可以清除项目而不会出现此问题。
不同的是时间,qazxsw poi是早期触发的,当时你无法清除这些物品,并且qazxsw poi被触发的时间要晚得多。