Reputation: 1114
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?
Upvotes: 3
Views: 3170
Reputation: 7537
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);
}
ObservableCollection<T>
called itemsToRemove
, with the same T
as your collection you are trying to modify.itemsToRemove
.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.
Upvotes: 1
Reputation: 81243
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);
}
Upvotes: 6