Удаление элемента из списка привязок WPF

У меня есть приложение WPF с ListBox (с именем listMyItems), которое успешно привязано к созданному мной классу MyItems. У меня есть список MyItems с именем currentMyItems, который затем назначается как ItemSource для ListBox. Все работает нормально, если я добавляю элемент в currentMyItems, он всплывает в списке и т.д. Проблема возникает, когда я пытаюсь удалить выбранный элемент в ListBox. Это код, который я использую:

currentMyItems.Remove((MyItem)listMyItems.SelectedItem);

Элемент исчезает из ListBox, но в следующий раз, когда я его обновляю, он снова появляется, поскольку никогда не удалялся. Какие-нибудь советы?


person mmvsbg    schedule 12.11.2013    source источник
comment
but the next time I update it что это означает? Вы обновляете список?   -  person PoweredByOrange    schedule 12.11.2013
comment
Да, я динамически добавляю в него элементы.   -  person mmvsbg    schedule 12.11.2013


Ответы (5)


Я думаю, вы можете быть сбиты с толку тем, как работает привязка данных. Когда вы привязываете свойство, вы говорите WPF искать значение этого свойства в другом месте.

Когда вы привязываете свойство ListBox.ItemsSource к currentMyItems, вы говорите WPF просмотреть список currentMyItems, чтобы найти его список элементов. Если currentMyItems является ObservableCollection вместо List<T>, то пользовательский интерфейс автоматически получит уведомление об обновлении связанного значения при добавлении или удалении элемента из коллекции.

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

Просто создайте один ObservableCollection<MyItem>, привяжите его к свойству ListBox.ItemsSource, а затем добавьте или удалите элементы из этой единственной коллекции. Это должно работать так, как вы ожидаете.

<ListBox x:Name="listMyItems" ItemsSource="{Binding MyItems}" />

и

MyItems.Add((MyItem)listMyItems.SelectedItem)
MyItems.Remove((MyItem)listMyItems.SelectedItem)

Если вам интересно, у меня также есть несколько статей для начинающих в моем блоге для пользователей WPF, которые изо всех сил пытаются понять DataContext. Вы можете ознакомиться с Понимание изменения мышления, когда переход с WinForms на WPF и Что это за DataContext, о котором вы говорите?

person Rachel    schedule 12.11.2013
comment
Обновление коллекции MyItems — это не все, что вам нужно сделать. Это будет работать для 1-го ListBox, но что, если вы хотите обновить 2-й ListBox, используя .SelectedItem 1-го ListBox? Выполнение MySelectedItems.Add((MyItem)listMyItems.SelectedItem) не обновляет это поле автоматически. Я слышал, что люди используют рефрен для реализации INotifyPropertyChanged, но не говорят, как это сделать. Просто добавить это так: public partial class MainWindow : Window, INotifyPropertyChanged вверху недостаточно. Как обновление ObservableCollection<MyItem> обновляет ListBox? Недостающий фрагмент здесь. - person vapcguy; 19.01.2017
comment
Ничего страшного - я разобрался. Вы должны установить свой .ItemsSource из 2-го поля на тот 2-й ObservableCollection<MyItem>, который вы создаете. Как только вы это сделаете, он обновится автоматически. Если вы никогда не устанавливаете свойство .ItemsSource в коде программной части, даже если вы делаете это в разметке XAML, изменения не вносятся. - person vapcguy; 19.01.2017

Если вы правильно привязали его к ObservableCollection, а currentMyItems является этой коллекцией. Это означает, что вы должны перезагрузить currentMyItems тем временем.

Также рассмотрите возможность привязки свойства SelectedItem вашего ListView — ваша модель представления вообще не должна знать о представлении.

person Andrzej Gis    schedule 12.11.2013
comment
+1 за рекомендацию привязать SelectedItem, чтобы разделить слои View и ViewModel. - person Rachel; 13.11.2013

Сделайте currentMyItems<MyItem> ObservableColection<MyItem>. Таким образом, он будет вызывать изменение свойства при каждом изменении, и пользовательский интерфейс соответственно обновляется.

person C_sharp    schedule 12.11.2013

Ваша исходная коллекция должна быть модифицирована (наследована от IList или ICollection). Если ваша исходная коллекция не поддерживает этот метод интерфейса Remove, вы не сможете удалить элемент из исходного кода.

Итак, когда вы хотите удалить элемент, вы должны привести ItemsSource к IList или ICollection:

var source = listbox.ItemsSource as IList ?? listbox.ItemsSource as ICollection;

а затем проверьте:

if (source == null) return;

тогда:

listbox.SelectedItems.ForEach(source.Remove);
listbox.Items.Refresh();
person Smagin Alexey    schedule 05.08.2014

Используя ObservableCollection, вы будете автоматически получать обновления пользовательского интерфейса.

Вы должны использовать ObservableCollection вместо List. Хорошо всегда использовать ObservableCollection вместо List, когда что-то связано с пользовательским интерфейсом.

person Kristian Nielsen    schedule 12.11.2013