2014-01-19 4 views
1

Я пытаюсь удалить выбранные элементы в ListBox, который привязан к ObservableCollection.Удалить выбранные элементы из списка (ObservableCollection)

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

"Коллекция была изменена; операция перечисления не может выполнить"

Что такое правильный способ сделать это?

+2

http://stackoverflow.com/questions/604831/collection-was-modified-enumeration-operation-may-not-execute –

+0

Специально прочитайте этот комментарий .. http://stackoverflow.com/questions/604831/ collection-was-modified-enumeration-operation-may-not-execute # comment13168776_604843 –

ответ

3

Вы не можете изменить коллекцию при ее перечислении, как видно из самого исключения.

Объяснение:

При удалении элемента из ObservableCollection, MyList.SelectedItems получает обновление с момента ObservableCollecton реализации INotifyCollectionChanged. Теперь selectedFiles указывает на ту же ссылку, которая приводит к ее модификации.

Решение

Вместо создать новый список и перечислить более, что таким образом, что любое изменение в ObservableCollection не отражает обратно в список, который вы перечисляете. Это будет работать:

var selectedFiles = MyList.SelectedItems.Cast<object>().ToList(); 
foreach (cListEntry item in selectedFiles) 
{ 
    _myList.Remove(item); 
} 
+0

Благодарим за объяснение и решение. Я не знал об этом. Это также, похоже, работает MyList.SelectedItems.Count! = 0) {_ myList.Remove ((cListEntry) MyList.SelectedItems [0]);} – Daniel

+0

Да, если вы хотите удалить только один элемент, это сработает. –

+1

+1 для правильного ответа. :) –

0

Это происходит при попытке изменить ObservableCollection<T>, привязанный к ListBox, например. Это, как вы имеете дело с этим:

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. Создать новую ObservableCollection<T> называется itemsToRemove, с тем же T как вашей коллекции, вы пытаетесь изменить.
  2. Итерируйте через свои узлы SelectedItems в своем ListBox. Добавьте их в itemsToRemove.
  3. Итерация через itemsToRemove. Извлеките ListBox ItemsSource в ObservableCollection<T> и удалите совпадения в itemsToRemove.

Ссылка: http://docs.telerik.com/devtools/wpf/controls/radgridview/managing-data/deleting-entry

Так что это означало бы, вы должны быть в состоянии сделать это:

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); 
} 

Я не уверен, что _myList есть, но вам не нужно, чтобы изменить его , Просто перейдите непосредственно в ListBox.

Смежные вопросы