WPF MVVM - 阻止值在UI上更新

20 浏览
0 Comments

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(IEnumerable collection)
        {
            foreach (var i in collection) Items.Add(i);
            OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, collection.ToList()));
        }
        ///  
        /// 从ObservableCollection(Of T)中移除指定集合中每个项的第一个匹配项。 
        ///  
        public void RemoveRange(IEnumerable collection)
        {
            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(IEnumerable collection)
        {
            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(IEnumerable collection) : base(collection) { }
    }
}

我现在遇到了这个错误:

附加信息:不支持范围操作。

错误出现在这里:

OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, collection.ToList()));

0
0 Comments

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更新,提高性能。

0