从WPF绑定列表框中删除一个项目。

4

我有一个WPF应用程序,其中包含一个ListBox(名为listMyItems),它已成功绑定到一个我创建的MyItems类。我有一个名为currentMyItems的MyItems列表,然后将其分配为ListBox的ItemSource。如果我向currentMyItems中添加项目,则该项目会在列表中弹出,等等。 问题出现在我尝试从ListBox中删除选定的项目时。这是我使用的代码:

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

该项从ListBox中消失,但下次更新时,它会弹回来,就好像从未被删除过。有什么建议吗?

1
“但下次我更新它”这究竟是什么意思?你是在重新填充列表吗? - Arian Motamedi
是的,我正在动态添加项目。 - mmvsbg
5个回答

13

我认为你可能对数据绑定的工作原理感到困惑。当你绑定属性时,你告诉WPF去其他地方查找该属性的值。

当你将 ListBox.ItemsSource 属性绑定到 currentMyItems 时,你告诉WPF去 currentMyItems 列表中查找其项目列表。如果 currentMyItems 是一个 ObservableCollection 而不是 List<T>,那么UI会在你添加或删除集合中的项目时自动接收通知以更新绑定值。

根据你在问题中提到的内容,听起来你有两个集合,其中一个被绑定,另一个用于在更改发生时重新创建第一个集合。这些都是不必要的。

只需创建一个 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”是什么?


1
更新MyItems集合似乎不是你需要做的全部。它可以用于第一个ListBox,但如果您想使用第一个ListBox的.SelectedItem更新第二个ListBox呢?执行MySelectedItems.Add((MyItem)listMyItems.SelectedItem)不会自动更新该框。我听说过人们使用“实现INotifyPropertyChanged”这句话,但没有说明如何实现。仅仅像这样添加:public partial class MainWindow : Window, INotifyPropertyChanged在顶部是不够的。如何通过更新ObservableCollection<MyItem>来更新ListBox?这里缺少一块拼图。 - vapcguy
1
没关系 - 我已经想通了。你必须将第二个框的.ItemsSource设置为你创建的第二个ObservableCollection<MyItem>。一旦你这样做了,它就会自动更新。如果你在代码后台没有设置.ItemsSource属性,即使你在XAML标记中这样做了,它也不会进行更改。 - vapcguy

3
如果你正确地将它绑定到一个ObservableCollection并且currentMyItems是那个集合。那么这意味着你必须在此期间重新加载了currentMyItems。
另外考虑绑定你的ListView的SelectedItem属性 - 你的视图模型不必知道视图的任何信息。

推荐将“SelectedItem”绑定到视图和视图模型层分开,以保持分离的状态。 - Rachel

2

您的源集合必须进行修改(继承自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();

1
currentMyItems<MyItem>更改为ObservableColection<MyItem>。这样,每当修改时,它将引发属性更改,UI会相应地更新。

0

通过使用ObservableCollection,您将自动获得UI上的更新。

在与UI有关的任何事情时,应该使用ObservableCollection而不是List。 一个好的习惯是始终使用ObservableCollection而不是List。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接