在MVVM中对ViewModel进行批量更改时,如何使用批处理,如BeginUpdate/EndUpdate
本文关键字:何使用 批处理 EndUpdate BeginUpdate ViewModel 中对 MVVM | 更新日期: 2023-09-27 18:24:41
在我使用MVVM的Silverlight应用程序中,我有一个图表(第三方ComponentOne),它绘制了大量数据,因此需要花费大量时间进行渲染。
我的ViewModel中有一个ObservableCollection(比如chartDataCollection),它绑定到图表的数据源。
在某些场景中,我在chartDataCollection中添加了100秒的项,这导致CollectionChange事件被触发100秒,并且每次都渲染图表,这需要花费大量时间。
在C#中,我是否可以将这些更新组合在一起,并在完成后只通知UI一次就像我们在Winforms世界中使用BeginUpdate和EndUpdate语句将数据添加到数据网格时所做的那样。
一种方法是实现自己的MyBatchObservableColleciton,派生或(更好地)嵌入List(或任何其他适当的集合)。实现修改innter集合并记录所有这些更改的方法。当您准备好将所有更改提交到WPF时,只需发送更改列表即可。以下是您可以做什么的子集示例(仅实现集合的"添加"功能):
class BatchObservableColleciton<T> : INotifyCollectionChanged, IEnumerable
{
public event NotifyCollectionChangedEventHandler CollectionChanged;
private List<T> _list;
private List<T> _addedItems;
public BatchObservableColleciton( ) {
_list = new List<T>( );
_addedItems = new List<T>( );
}
public IEnumerator GetEnumerator( )
{
return _list.GetEnumerator( );
}
public void Add( T item )
{
_list.Add( item );
_addedItems.Add( item );
}
public void Commit( ) {
if( CollectionChanged != null ) {
CollectionChanged( this, new NotifyCollectionChangedEventArgs(
NotifyCollectionChangedAction.Add, _addedItems ) );
}
_addedItems.Clear( );
}
}
我自己从来没有尝试过,但我认为这是一条路。谷歌自定义&ObservableCollection。虽然不完全准确,但很少有实现。
不要使用ObservableCollection
,而是使用利用INotifyPropertyChanged
模式的简单IEnumerable
属性。
private IEnumerable _ChartDataCollection;
public IEnumerable ChartDataCollection
{
get
{
return _ChartDataCollection;
}
set
{
if (_ChartDataCollection != value)
{
_ChartDataCollection = value;
NotifyPropertyChanged("ChartDataCollection");
}
}
}
为什么不为所有更改使用一个单独的集合,然后合并这两个集合,并在完成后将其分配给您的公共集合?这将只触发PropertyChanged
事件一次。
// Create a new List that contains objects from your Collection
var list = new List<SomeItem>(SomeCollection);
foreach(var item in newItems)
{
// Add new items to list
}
// Reset collection w/ items from List
SomeCollection = new ObservableCollection<SomeItem>(list);