WPF MVVM - 阻止值在UI上更新
WPF MVVM - 阻止值在UI上更新
我有一个使用MVVM数据绑定的WPF应用程序。我正在向ObservableCollection<...>
中添加项目,而且确实有很多项目。
现在我想知道,每次我添加一个项目到集合中,它是否会立即触发事件并造成不必要的开销?如果是这样,我是否可以暂时禁用事件通知,并在我的代码末尾手动触发它一次,这样如果我添加了1万个项目,它只会被触发一次,而不是1万次?
更新:我尝试使用这个类:
using System; using System.Linq; using System.Collections.Specialized; using System.Collections.Generic; namespace MyProject { ////// 表示一个动态数据集合,当项目添加、移除或整个列表刷新时提供通知。 /// ///public class ObservableCollection : System.Collections.ObjectModel.ObservableCollection { /// /// 将指定集合的元素添加到ObservableCollection(Of T)的末尾。 /// public void AddRange(IEnumerablecollection) { foreach (var i in collection) Items.Add(i); OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, collection.ToList())); } /// /// 从ObservableCollection(Of T)中移除指定集合中每个项的第一个匹配项。 /// public void RemoveRange(IEnumerablecollection) { foreach (var i in collection) Items.Remove(i); OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, collection.ToList())); } /// /// 清除当前集合并用指定项替换它。 /// public void Replace(T item) { ReplaceRange(new T[] { item }); } ////// 清除当前集合并用指定集合替换它。 /// public void ReplaceRange(IEnumerablecollection) { List old = new List (Items); Items.Clear(); foreach (var i in collection) Items.Add(i); OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, collection.ToList())); } /// /// 初始化 System.Collections.ObjectModel.ObservableCollection(Of T) 类的新实例。 /// public ObservableCollection() : base() { } ////// 初始化 System.Collections.ObjectModel.ObservableCollection(Of T) 类的新实例,该实例包含从指定集合复制的元素。 /// /// collection: 要复制元素的集合。 ///参数 collection 不能为 null。 public ObservableCollection(IEnumerablecollection) : base(collection) { } } }
我现在遇到了这个错误:
附加信息:不支持范围操作。
错误出现在这里:
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, collection.ToList()));
WPF MVVM - 阻止值在UI上更新的问题
在WPF MVVM中,有时我们希望在更新集合时,不要在UI上立即更新值,而是在完成所有更新后一次性更新。然而,在默认的ObservableCollection中,并没有提供AddRange方法来实现这一点。本文将讨论该问题的原因以及解决方法。
问题的原因是ObservableCollection没有内置的AddRange方法,因此无法一次性更新值。为了解决这个问题,我们可以自己编写一个ObservableCollection,并实现AddRange方法。通过在"holder collection"中添加所有的10k元素,然后在完成后使用我们自己的ObservableCollection的AddRange方法来实现一次性更新。
可以在以下链接中找到更多关于如何实现自己的AddRange方法的信息:
- [ObservableCollection Doesn't support AddRange method....](https://stackoverflow.com/questions/670577)
- [AddRange and ObservableCollection](http://blogs.msdn.com/b/nathannesbit/archive/2009/04/20/addrange-and-observablecollection.aspx)
有趣的是,为什么ObservableCollection没有内置的AddRange方法呢?
实际上,我不知道。很希望它能够像内置方法一样提供AddRange方法,但或许如Eric Lippert有时所说的那样:因为没有人去实现它...
在尝试实现自己的AddRange方法时,有读者遇到了一些问题。在调用OnCollectionChanged方法时,他们收到了"Constructor supports only the 'Reset' action."的错误提示。这是因为他们没有使用接受添加的项列表的构造函数。通过使用collection.ToList()作为第二个参数,可以解决这个问题。
然而,他们又遇到了"Range actions are not supported."的错误提示。为了解决这个问题,可以尝试调用this.OnPropertyChanged("Count")和this.OnPropertyChanged("Item[]")来通知更改Count和Items集合。
最后,有读者问到等效的事件是什么。事实上,这是一个小包装函数,它实际上是对通知的封装。可以在[这里](http://msdn.microsoft.com/en-us/library/ms743695.aspx)找到更多信息。
要解决WPF MVVM中阻止值在UI上更新的问题,可以通过自己编写ObservableCollection并实现AddRange方法来实现一次性更新。虽然这需要一些额外的工作,但可以避免频繁的UI更新,提高性能。