Reputation: 654
When a box that is checked is unchecked I want to remove that item. The trouble is check/unchecking seems to happen after the ItemCheck method is called. So, when I remove an item that messes up the e.Index so it does the check/uncheck on the item after the one I remove or throws an error if it is the last one.
I found this: Getting the ListView ItemCheck to stop! which has the tip of resetting the e.NewValue which partially works, but it still throws an error when I remove the last item.
The reason I have not simply used one of the mouse events is that I want keyboard navigation to still be possible just in case.
Here is the code I have now.
private void checked_ItemCheck(object sender, ItemCheckEventArgs e)
{
if (e.NewValue == CheckState.Unchecked)
{
checked.Items.RemoveAt(e.Index);
e.NewValue = CheckState.Checked;
}
}
Thanks for the help
Upvotes: 3
Views: 4066
Reputation: 28530
It sounds like the only problem you're still experiencing is the call to e.NewValue
after you remove the last item, right? If that's the case, try this:
private void checked_ItemCheck(object sender, ItemCheckEventArgs e)
{
if (e.NewValue == CheckState.Unchecked)
{
checked.Items.RemoveAt(e.Index);
// If there are no items left, skip the CheckState.Checked call
if (checked.Items.Count > 0)
{
e.NewValue = CheckState.Checked;
}
}
}
UPDATE
Ok - I got it to work, though I'm not sure how pretty it is. I used the SelectedIndexChanged event:
private void checked_SelectedIndexChanged(object sender, EventArgs e)
{
CheckedListBox clb = (CheckedListBox)sender;
int index = clb.SelectedIndex;
// When you remove an item from the Items collection, it fires the SelectedIndexChanged
// event again, with SelectedIndex = -1. Hence the check for index != -1 first,
// to prevent an invalid selectedindex error
if (index != -1 && clb.GetItemCheckState(index) == CheckState.Unchecked)
{
clb.Items.RemoveAt(index);
}
}
I've tested this in VS 2010 and it works.
Upvotes: 5