Очистить CheckedListBox после события ItemCheck - PullRequest
0 голосов
/ 09 сентября 2018

В моем проекте Windows Forms, написанном на C #, я пытаюсь очистить CheckedListBox после проверки последнего элемента.

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

В этом примере программа выдает исключение NullReferenceException после проверки последнего элемента.

Может ли кто-нибудь объяснить, почему это происходит и как я могу справиться с этим?

Заранее спасибо!

Ответы [ 2 ]

0 голосов
/ 09 сентября 2018

Измените свой код для запуска логики после обновления состояния проверки элемента:

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

Согласно документации , по умолчанию, когда возникает событие ItemCheck,состояние проверки элемента не обновляется до тех пор, пока не произойдет событие ItemCheck.Это означает, что он пытается обновить состояние проверки элемента после выполнения кода, который есть в обработчике событий.В результате в вашем коде он пытается обновить состояние проверки элемента после удаления элемента из коллекции элементов, поэтому возникает исключение.Вы можете увидеть, что происходит в трассировке стека, а также в исходном коде элемента управления.

В приведенном выше коде, используя BeginInvoke, мы откладываем запуск кода после обновления состояния проверки.Вы можете прочитать больше об этом в этом посте .

0 голосов
/ 09 сентября 2018

Это происходит потому, что после очистки элементов из checklistbox происходит некоторый внутренний вызов (System.Windows.Forms.CheckedListBox.CheckedItemCollection.SetCheckedState), который вызывается позже и по-прежнему действует на элементы. Так что выбрасывает NullReferenceException.

Если вы зарегистрируете событие SelectedIndexChanged, вы можете очистить элементы без этой проблемы.

Разница в сроках, ItemCheck срабатывает рано, в это время вы не можете очистить предметы, а SelectedIndexChanged срабатывает намного позже.

...