ItemCheck事件后清除CheckedListBox

时间:2018-09-09 11:58:57

标签: c# .net winforms checkedlistbox

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

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

在此示例中,在我检查了最后一项之后,程序将引发NullReferenceException。

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

谢谢!

2 个答案:

答案 0 :(得分: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 :(得分:1)

这是因为从checklistbox清除项目后,会有一些内部调用(System.Windows.Forms.CheckedListBox.CheckedItemCollection.SetCheckedState)稍后会被调用,并且仍对项目起作用。因此它抛出了NullReferenceException

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

不同之处在于时间,ItemCheck较早触发,那时您无法清除项目,而SelectedIndexChanged较晚触发。