当使用 WPF 数据绑定(bind)时,我显然不能按照 MyCollection = new CollectionType<Whatever>( WhateverQuery() );
的方式进行操作因为绑定(bind)引用了旧集合。到目前为止,我的解决方法是 MyCollection.Clear();
接下来是 foreach 做 MyCollection.Add(item);
- 这对性能和美观来说都非常糟糕。
ICollectionView
,虽然很整洁,但也没有解决问题,因为它是 SourceCollection
属性是只读的;真可惜,因为那将是一个不错且简单的解决方案。
其他人是如何处理这个问题的?应该提到的是,我正在做 MVVM,因此无法翻阅各个控件绑定(bind)。我想我可以围绕 ObservableCollection
做一个包装运动 ReplaceSourceCollection()
方法,但在采用该方法之前,我想知道是否还有其他一些最佳实践。
编辑:
对于 WinForms,我会将控件绑定(bind)到 BindingSource
,允许我简单地更新它的 DataSource
属性(property)并调用ResetBindings()
方法 - 很快,底层集合有效地改变了。我会期望 WPF 数据绑定(bind)支持开箱即用的类似场景吗?
示例(伪)代码:WPF 控件(ListBox、DataGrid,无论您喜欢什么)都绑定(bind)到 Users
属性(property)。我意识到集合应该是只读的,以避免 ReloadUsersBad()
所展示的问题。 ,但是这个例子的错误代码显然无法编译 :)
public class UserEditorViewModel
{
public ObservableCollection<UserViewModel> Users { get; set; }
public IEnumerable<UserViewModel> LoadUsersFromWhateverSource() { /* ... */ }
public void ReloadUsersBad()
{
// bad: the collection is updated, but the WPF control is bound to the old reference.
Users = new ObservableCollection<User>( LoadUsersFromWhateverSource() );
}
public void ReloadUsersWorksButIsInefficient()
{
// works: collection object is kept, and items are replaced; inefficient, though.
Users.Clear();
foreach(var user in LoadUsersFromWhateverSource())
Users.Add(user);
}
// ...whatever other stuff.
}
最佳答案
如果对象 MyCollection
是实现 INotifyPropertyChanged
的对象,您可以简单地替换集合。
一个例子:
public class MyClass : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private ObservableCollection<Whatever> _myCollection;
private void NotifyChanged(string property)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
public ObservableCollection<Whatever> MyCollection
{
get
{
return _myCollection;
}
set
{
if (!ReferenceEquals(_myCollection, value))
{
_myCollection = value;
NotifyChanged("MyCollection");
}
}
}
}
有了这个,当您分配一个集合时,WPF 会检测到这一点并且所有内容都会更新。
这就是我解决这个问题的方法。
关于c# - WPF:在没有清除/添加的情况下替换数据绑定(bind)集合内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4302945/