Dimitris Iliadis
Dimitris Iliadis

Reputation: 2397

Can't remove items from ComboBox without crashing

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

Answers (4)

Yargo
Yargo

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

denis morozov
denis morozov

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

Dimitris Iliadis
Dimitris Iliadis

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

qamar
qamar

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

Related Questions