当ObservableCollection发生变化时更新CollectionViewSource WP7
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了当ObservableCollection发生变化时更新CollectionViewSource WP7相关的知识,希望对你有一定的参考价值。
我有一个ObservableCollection
为我的基础项目列表。我有两个 CollectionViewSource
是数据的不同过滤器。我希望任何发生的变化都能反映在数据的 CollectionViewSource
.
在我的视图模型构造函数中,我设置了过滤谓词。然后我获取数据并将其添加到 ObservableCollection
. 我已经订阅了 CollectionChanged
事件,并在那里刷新CVS。
但我看到一些非常奇怪的事情。要么这些项目不显示在我的 ListBox
绑定到CVS的,否则会出现重复。如果我调用 Refresh
在中央统计局之外的 CollectionChanged
事件后,我改变了 ObservableCollection
我觉得一切都很好,我很想在集合发生变化的时候,能够直接刷新,而不用担心每次做了什么改变后,都要调用刷新。我真的很希望能够在集合发生变化时直接刷新,而不用担心每次做了改变集合的事情后都要调用刷新。
public MyViewModel()
{
oc.CollectionChanged += OcCollectionChanged;
cvs1.Source = oc;
cvs1.View.Filter = new Predicate<object>( ... );
cvs2.Source = oc;
cvs2.View.Filter = new Predicate<object>( ... );
foreach( var data in myData )
{
oc.Add( data );
}
}
private void OcCollectionChanged( object sender, NotifyCollectionChangedEventArgs e )
{
cvs1.View.Refresh();
cvs2.View.Refresh();
}
CollectionViewSource
没有实现 INotifyPropertyChanged
因此,要想将任何底层数据的变化传递到UI中,你需要调用 Refresh
就像你已经在做的那样。CollectionViewSource
也是数据源不可知的,所以事实上,源是个 ObservableCollection
引起属性变更通知的是不重要的,因为 CollectionViewSource
是不听的。
我认为,当集合发生变化时,手动刷新视图是最好的解决方案,而不需要重新思考你的数据结构。
我使用的是一个修改过的 ObservableCollection
类,特别是克服上述限制的类(CollectionChangedEvent
事件多次发生),发现 这里。(ObservableCollectionEx - 阻止CollectionChangedEvent,直到通过添加一个AddRange方法将所有的人都添加进来)
我已经使用它2年了,它对于大的集合变化非常好用。
更新: 看来那个链接已经关闭了,所以这里是代码。
public class ObservableCollectionEx<T> : ObservableCollection<T>
{
public ObservableCollectionEx()
: base()
{
_suspendCollectionChangeNotification = false;
}
bool _suspendCollectionChangeNotification;
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
if(!_suspendCollectionChangeNotification)
{
base.OnCollectionChanged(e);
}
}
public void SuspendCollectionChangeNotification()
{
_suspendCollectionChangeNotification = true;
}
public void ResumeCollectionChangeNotification()
{
_suspendCollectionChangeNotification = false;
}
public void AddRange(IEnumerable<T> items)
{
this.SuspendCollectionChangeNotification();
int index = base.Count;
try
{
foreach(var i in items)
{
base.InsertItem(base.Count, i);
}
}
finally
{
this.ResumeCollectionChangeNotification();
var arg = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset);
this.OnCollectionChanged(arg);
}
}
}
问题是... ObservableCollection
有其局限性。 考虑一下你的代码中的那个循环,它调用了多少次的 Add
方法? 因此,改变了的事件会被触发多少次,刷新方法会被调用多少次? 当如此多的变化连续发生时,这段代码陷入困境也就不足为奇了。
在 ObservableCollection
是很好的,当它最初被加载时,它的变化事件就会被监控,然后从这一点上进行相对不频繁的小变化。 对于大规模的变化,最好是加载一个全新的实例,然后将这个新实例分配给一个属性。
让属性设置者重新分配 Source
上的属性 CollectionViewSource
对象。 如果你还想观察这个集合,你也可以在setter中分离并附加你的事件处理程序。
以上是关于当ObservableCollection发生变化时更新CollectionViewSource WP7的主要内容,如果未能解决你的问题,请参考以下文章
wpf中,当DataGrid.ItemsSource与ObservableCollection绑定后,值变化时,DataGrid如何刷新?