Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remove selected items from Listbox (ObservableCollection)

I am trying to remove selected items in a ListBox which is bound to ObservableCollection.

var selectedFiles = MyList.SelectedItems;
foreach (cListEntry item in selectedFiles)
{
   _myList.Remove(item);
}

"Collection was modified; enumeration operation may not execute"

What is the proper way of doing this?

like image 648
Daniel Avatar asked Mar 12 '26 22:03

Daniel


2 Answers

You can't modify the collection while enumerating it as evident from the exception itself.

Explanation:

When you remove item from ObservableCollection, MyList.SelectedItems gets update since ObservableCollecton implement INotifyCollectionChanged. Now, selectedFiles is pointing to same reference which results in modifying it.

Solution

Instead create a new list and enumerate over that so that any change in ObservableCollection doesn't reflect back to list which you are enumerating. This will work:

var selectedFiles = MyList.SelectedItems.Cast<object>().ToList();
foreach (cListEntry item in selectedFiles)
{
   _myList.Remove(item);
}
like image 77
Rohit Vats Avatar answered Mar 14 '26 11:03

Rohit Vats


This happens when trying to modify an ObservableCollection<T> that is bound to a ListBox, for example. This is how you deal with that:

ObservableCollection<Employee> itemsToRemove = new ObservableCollection<Employee>();

foreach (Employee item in lsbxNames.SelectedItems)
{
    itemsToRemove.Add(item);
}
foreach (Employee item in itemsToRemove)
{
    ((ObservableCollection<Employee>)lsbxNames.ItemsSource).Remove(item);
}
  1. Create a new ObservableCollection<T> called itemsToRemove, with the same T as your collection you are trying to modify.
  2. Iterate through your nodes of SelectedItems in your ListBox. Add them to itemsToRemove.
  3. Iterate through itemsToRemove. Cast the ListBox ItemsSource to an ObservableCollection<T> and remove the matches in itemsToRemove from it.

Reference: http://docs.telerik.com/devtools/wpf/controls/radgridview/managing-data/deleting-entry

So this would mean you should be able to do this:

ObservableCollection<cListEntry> itemsToRemove = new ObservableCollection<cListEntry>();

foreach (cListEntry item in MyList.SelectedItems)
{
    itemsToRemove.Add(item);
}
foreach (cListEntry item in itemsToRemove)
{
    ((ObservableCollection<cListEntry>)MyList.ItemsSource).Remove(item);
}

I'm not sure what _myList is, but you don't need to modify it. Just go directly to the ListBox.

like image 45
vapcguy Avatar answered Mar 14 '26 11:03

vapcguy



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!