【发布时间】:2018-01-16 15:17:42
【问题描述】:
我在一个 MVVM C# 项目中。
我想显示一个对象列表。 我想添加和删除此列表中的项目,并更改此列表中的项目。
所以我选择了 BindingList 而不是 ObservableCollection,如果项目发生了变化,它不会被注意到。 (我还测试了 Web 中的 ObservableCollectionEx,但它的行为与我的 BindingList 相同)。 但是当项目改变时列表框不会改变。 (添加和删除项目在列表框中更新)
在我的 XAML 中
<ListBox DisplayMemberPath="NameIndex" ItemsSource="{Binding Profiles}" SelectedItem="{Binding SelectedProfile}">
或使用 ItemTemplate 替代
<ListBox DockPanel.Dock="Right" ItemsSource="{Binding Profiles}" SelectedItem="{Binding SelectedProfile}" Margin="0,10,0,0">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding NameIndex}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
在我的 ViewModel 中(ViewModelBase 正在实现 INotifyPropertyChanged 等)
public class ProfileListViewModel : ViewModelBase
{
private BindingList<Profile> profiles;
public BindingList<Profile> Profiles
{
get
{
return profiles;
}
set
{
profiles = value;
RaisePropertyChanged();
}
}
我的项目也在实施 INotifyPropertyChanged,我在我的 Setter 中调用 OnPropertyChanged("Name")。
我的模型
public class Profile : INotifyPropertyChanged
{
public Profile(){}
public int ProfileID { get; set; }
private string name;
public string Name
{
get
{
return name;
}
set
{
name = value;
OnPropertyChanged("Name");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
用 ViewModel 连接 View(BindingList 在 View 之前初始化)
ProfileListViewModel plvw= new ProfileListViewModel(message.Content);
var profileView = new ProfileListView(plvw);
profileView.ShowDialog();
在 View.xaml.cs 中
public ProfileListView(ProfileListViewModel plvw)
{
InitializeComponent();
DataContext = plvw;
}
当我更改对象的名称时,我会收到我在 ViewModel (Profiles.ListChanged += Profiles_ListChanged;) 中订阅的 ListChanged 事件以进行测试,但 ListBox 中的项目没有改变。
我做错了什么? 如何获取更新的列表框?
【问题讨论】:
-
NameIndex 在配置文件类型中不存在。您在 ListBox 项中看到任何文本吗?
-
DisplayMemberPath 应该是“Name”而不是“NameIndex”
-
如果你想让别人知道你的代码出了什么问题,你必须提供一个好的minimal reproducible example,它可以可靠地重现你所看到的问题。也就是说,您选择
BindingList<T>而不是ObservableCollection<T>的原因对我来说似乎是似是而非。集合不是处理单个项目更新的东西。相反,用于在视图中显示项目的模板被绑定到每个项目,并且每个项目的属性更改通知由适当的模板视图实例观察。这同样适用于ObservableCollection<T>和BindingList<T>。 -
“我使用 ObserveableCollection 并且我更改了一个 Item 我没有收到 CollectionChanged 事件” -- 为什么你想要一个
CollectionChanged事件而不是集合,而是集合的一个元素,它已经改变了? “你能给我一个绑定到每个项目的模板的例子吗?” -- 你当然可以使用你最喜欢的网络搜索和/或 Stack Overflow 搜索来查找关于使用 @ 的讨论987654334@ItemControl。 -
您真的应该发布 NameIndex 的代码。我假设这是一个计算属性,您需要做的是在名称的设置器中调用
OnPropertyChanged(nameof(NameIndex))。
标签: c# wpf data-binding