Reputation: 710
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
Reputation: 25
This works for multiple and single selections in WPF.
while (xListBox.SelectedItems.Count > 0)
{
xListBox.Items.RemoveAt(SavedItemsListBox.SelectedIndex);
}
Upvotes: 0
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
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
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
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
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
Reputation: 8533
Simple just like this:
while (lst.SelectedItems.Count > 0)
{
lst.Items.Remove(lst.SelectedItems[0]);
}
Upvotes: 10
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
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