Reputation: 2397
In my application I'd like to give the user the option to delete items from a ComboBox
control by the press of the Del
button. I have managed to effectively do the first part, but what I can't seem to accomplish is actually delete an item (especially when it's the last one remaining) from the control without the whole application crashing. Why is that? Here's my code. It always throws an ArgumentOutOfRange exception when the last item is removed and contains the message InvalidArgument=Value of '0' is not valid for 'index'.
private void cboSource_KeyDown(object sender, KeyEventArgs e)
{
deleteItem(cboSource, e);
}
private void cboTarget_KeyDown(object sender, KeyEventArgs e)
{
deleteItem(cboTarget, e);
}
private void deleteItem(ComboBox comboBox, KeyEventArgs e)
{
if (e.KeyCode == Keys.Delete)
{
comboBox.Items.Remove(comboBox.SelectedItem);
}
}
I have two ComboBoxes and a function to delete the items, but I guess it won't be much of a problem now, right?
EDIT: The crash usually happens when no items are left and the control loses focus.
Upvotes: 3
Views: 2844
Reputation: 58
I solved this problem by closing the drop-down list, before remove the last element.
private void cmbUserLogin_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Delete && cmbUserLogin.DroppedDown)
{
if (cmbUserLogin.Items.Count > 0)
{
int currentItem = cmbUserLogin.SelectedIndex;
if (currentItem >= 0)
{
// todo
if (cmbUserLogin.Items.Count == 1)
cmbUserLogin.DroppedDown = false;
cmbUserLogin.Items.RemoveAt(currentItem);
}
}
e.Handled = true;
}
}
Upvotes: 2
Reputation: 6316
I created a small sample in WPF
with your code and it doesn't crash. From what I see you are not using the WPF
. Still, to make you feel better - your code should be work out of the box. But there are a couple of things that I see from your post:
1.The error that you are getting ArgumentOutOfRange
happens when you try to manipulate an item in the list using the index that cannot get you that item. So if there are 3 items in the list and you try to access list.Items[3], you'll get that error.
2.InvalidArgument=Value of '0' is not valid for 'index'
tells me that you are not only accessing the index that doesn't exist, but you are accessing the element with index zero, assuming that the combo box list has at least one element in it. So what's happening is that you are somehow attempting to delete the last item in the combo box, when the combo box is already empty. Hence the error.
To solve that:
//before delete, check if combo box has items
if(comobBox.Items.Count > 0)
{
comboBox.Items.Remove(comboBox.SelectedItem);
//edit: this might help with that last crash (from comments)
if(comboBox.Items.Count == 0)
comboBox.SelectedItem = null;
}
That's not a bad practice to check especially if there are multiple entry points to the same code, not even mentioning multi-threaded possibilities..
Also, it might not be a bad idea to check whether the selected item is not null as well.
Upvotes: 0
Reputation: 2397
Here's a fix I figured out by messing with the code a bit. I'm not entirely sure as to why it works, but it works. This by no means is a viable solution for me, though, as it still is a "work around", in the sense that I'm working around the problem and am not actually solving it. Until someone finds a better way, I guess I will stick to this. Here is the code:
private void deleteItem(ComboBox comboBox, KeyEventArgs e)
{
if (e.KeyCode == Keys.Delete)
{
if (comboBox.Items.Count == 1)
{
comboBox.Items.Clear();
return;
}
comboBox.Items.Remove(comboBox.SelectedItem);
e.Handled = true; // I do not think this really contributes anything in this case.
}
}
Upvotes: 0
Reputation: 1447
You might add a default item to the combox which will never be deleted and likely to the first item or you can reinitialize an empty item list to avoid crash.
Upvotes: 0