【发布时间】:2010-11-29 10:43:50
【问题描述】:
当使用 WPF 数据绑定时,我显然无法按照MyCollection = new CollectionType<Whatever>( WhateverQuery() ); 的方式执行某些操作,因为绑定引用了旧集合。到目前为止,我的解决方法是 MyCollection.Clear();,然后是一个 foreach 做 MyCollection.Add(item); - 这对性能和美观都非常不利。
ICollectionView,虽然很简洁,但也不能解决问题,因为它的SourceCollection 属性是只读的;太可惜了,因为那将是一个不错且简单的解决方案。
其他人是如何处理这个问题的?应该提到的是,我正在做 MVVM,因此无法通过单独的控件绑定进行翻找。我想我可以使用ReplaceSourceCollection() 方法围绕ObservableCollection 进行包装,但在走这条路之前,我想知道是否还有其他最佳实践。
编辑:
对于 WinForms,我会将控件绑定到 BindingSource,允许我简单地更新它的 DataSource 属性并调用 ResetBindings() 方法 - 很快,底层集合有效地改变了。我本来希望 WPF 数据绑定能够开箱即用地支持类似的场景?
示例(伪)代码:WPF 控件(ListBox、DataGrid,无论你喜欢什么)绑定到Users 属性。我意识到集合应该是只读的以避免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.
}
【问题讨论】:
-
你能发一些代码吗?
-
+1 好问题。我已经有一段时间没有在 WPF 中做任何事情了,但是另一种语言的另一个框架有类似的概念,并通过停止运行循环、更改大量属性然后取消暂停运行循环来解决这个问题。我正在寻找类似的东西。
标签: c# wpf data-binding