Cristo
Cristo

Reputation: 710

Delete selected items from listbox

I want to do that but, the listbox changes on every deletion, so it throws runtime exception even if I tried to do a new object.

I tried like this:

ListBox.SelectedObjectCollection selectedItems = new ListBox.SelectedObjectCollection(lstClientes);
   selectedItems = lstClientes.SelectedItems;
if (lstClientes.SelectedIndex != -1)
{ 
    foreach (string s in selectedItems)
        lstClientes.Items.Remove(s);
}
else
    MessageBox.Show("Debe seleccionar un email");

Upvotes: 27

Views: 119034

Answers (10)

Frext
Frext

Reputation: 25

This works for multiple and single selections in WPF.

while (xListBox.SelectedItems.Count > 0)
{
    xListBox.Items.RemoveAt(SavedItemsListBox.SelectedIndex);
}

Upvotes: 0

Cody Rees
Cody Rees

Reputation: 21

To build on Patrick's answer I tend to use a reverse index removal as it retains the index of items pending removal while they're being removed without removing identical items.

private void BtnDelete_Click(object sender, EventArgs e) {
    if (listBox.SelectedIndex == -1) {
        return;
    }

    // Remove each item in reverse order to maintain integrity
    var selectedIndices = new List<int>(listBox.SelectedIndices.Cast<int>());
    selectedIndices.Reverse();
    selectedIndices.ForEach(index => listBox.Items.RemoveAt(index));
}

Upvotes: 2

Peetinun
Peetinun

Reputation: 51

lst.Items.Remove(lst.Items[lst.SelectedIndex]);

You can use this if you don't want to loop

Note: This only works to remove 1 item (multiple selections it will only remove the first selected item)

Upvotes: 5

Zachary Canann
Zachary Canann

Reputation: 1231

I encountered this same problem today and wanted something a bit cleaner, and came up with this Linq solution:

foreach (int index in myListBox.SelectedIndices.Cast<int>().Select(x => x).Reverse())
    myListBox.Items.RemoveAt(index);

Basically the same as Patrick's solution of iterating backwards and removing selected items. However instead of iterating backwards, we reverse the list of items to remove and iterate forwards. We no longer iterate over the original enumeration, so we are allowed to remove items within the foreach.

Upvotes: 1

Yusufm.Salh
Yusufm.Salh

Reputation: 39

Create a global variable:

public partial class Form1 : Form
    {

        Int32 index;
    }

Then at the selected index change save that index in the var you defined :

 private void lsbx_layers_SelectedIndexChanged(object sender, EventArgs e)
        {

           layerindex = lsbx_layers.SelectedIndices[0];//selected index that has fired the event
         }

Finally ,remove the element :

 lsbx_layers.Items.RemoveAt(Layerindex);

Upvotes: -1

Azaz Khan
Azaz Khan

Reputation: 106

This is the most easiest way to remove selected items

 for(int v=0; v<listBox1.SelectedItems.Count; v++) {
            listBox1.Items.Remove(listBox1.SelectedItems[v]);
        }

Upvotes: 0

Олег Ладыко
Олег Ладыко

Reputation: 112

I found better solution.

        if (listBoxIn.SelectedItems.Count != 0)
        {
            while (listBoxIn.SelectedIndex!=-1)
            {
                listBoxIn.Items.RemoveAt(listBoxIn.SelectedIndex);                  
            }
        }

Upvotes: 1

ninhjs.dev
ninhjs.dev

Reputation: 8533

Simple just like this:

while (lst.SelectedItems.Count > 0)
{
   lst.Items.Remove(lst.SelectedItems[0]);
}

Upvotes: 10

Patrick Quirk
Patrick Quirk

Reputation: 23747

You can't modify a collection while iterating (using a foreach) through it. Instead use a reverse for loop:

ListBox.SelectedObjectCollection selectedItems = new ListBox.SelectedObjectCollection(lstClientes);
selectedItems = lstClientes.SelectedItems;

if (lstClientes.SelectedIndex != -1)
{ 
    for (int i = selectedItems.Count - 1; i >= 0; i--)
        lstClientes.Items.Remove(selectedItems[i]);
}
else
    MessageBox.Show("Debe seleccionar un email");

Using a reverse loop ensures you don't skip over any after removing them.

Upvotes: 47

horgh
horgh

Reputation: 18534

selectedItems = lstClientes.SelectedItems;

This line does not create a new collection, but sets a reference to the one in a listbox. So you are iterating through a collection and try to remove items from it at once. It is not possible

You could use this, for example:

foreach (string s in lstClientes.SelectedItems.OfType<string>().ToList())
   lstClientes.Items.Remove(s);

Upvotes: 13

Related Questions