我可以暂时禁用WPF数据绑定更改吗? [英] Can I somehow temporarily disable WPF data binding changes?

查看:113
本文介绍了我可以暂时禁用WPF数据绑定更改吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用MVVM数据绑定的WPF应用程序。我将项目添加到 ObservableCollection< ...> 中,其中很多都是。



现在我我想知道每当我加入一个收藏,它会立即触发事件并造成不必要的开销?如果是这样,我可以暂时禁用事件通知,并在我的代码末尾手动触发一次,以便如果我添加10k项目,它只会被触发一次,而不是10k次?



更新:我尝试过这个类:

  using System; 
使用System.Linq;
使用System.Collections.Specialized;
使用System.Collections.Generic;

命名空间MyProject
{

///< summary>
///表示一个动态数据集合,当项目被添加,删除或整个列表刷新时提供通知。
///< / summary>
///< typeparam name =T>< / typeparam>
public class ObservableCollection< T> :System.Collections.ObjectModel.ObservableCollection< T>
{

///< summary>
///将指定集合的​​元素添加到ObservableCollection(Of T)的末尾。
///< / summary>
public void AddRange(IEnumerable< T>集合)
{
foreach(var i in collection)Items.Add(i);
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add,collection.ToList()));
}

///< summary>
///从ObservableCollection(Of T)中删除指定集合中每个项目的第一次发生。
///< / summary>
public void RemoveRange(IEnumerable< T>集合)
{
foreach(var i in collection)Items.Remove(i);
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove,collection.ToList()));
}

///< summary>
///清除当前集合并将其替换为指定的项目。
///< / summary>
public void Replace(T item)
{
ReplaceRange(new T [] {item});
}
///< summary>
///清除当前集合并将其替换为指定的集合。
///< / summary>
public void ReplaceRange(IEnumerable< T>集合)
{
列表< T> old = new List< T>(Items);
Items.Clear();
foreach(var i in collection)Items.Add(i);
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace,collection.ToList()));
}

///< summary>
///初始化System.Collections.ObjectModel.ObservableCollection(Of T)类的新实例。
///< / summary>
public ObservableCollection():base(){}

///< summary>
///初始化包含从指定集合复制的元素的System.Collections.ObjectModel.ObservableCollection(Of T)类的新实例。
///< / summary>
///< param name =collection> collection:复制元素的集合。< / param>
///< exception cref =System.ArgumentNullException> collection参数不能为空。< / exception>
public ObservableCollection(IEnumerable< T>集合):base(collection){}
}
}

我现在收到这个错误:


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


错误出现在这里:

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


解决方案

一个非常快速和容易的方法是将ObservableCollection和当调用AddRange时挂起通知。有关澄清,请参阅以下博客文章


I have a WPF application that uses MVVM data bindings. I am adding items to an ObservableCollection<...> and quite many of them indeed.

Now I am wondering that every time I add one to the collection, does it instantly fire the event and cause unnecessary overhead? If so, can I somehow temporarily disable the event notifications and manually fire it once at the end of my code so that if I add 10k items, it gets only fired once, rather than 10k times?

Update: I tried having this class:

using System;
using System.Linq;
using System.Collections.Specialized;
using System.Collections.Generic;

namespace MyProject
{

    /// <summary> 
    /// Represents a dynamic data collection that provides notifications when items get added, removed, or when the whole list is refreshed. 
    /// </summary> 
    /// <typeparam name="T"></typeparam> 
    public class ObservableCollection<T> : System.Collections.ObjectModel.ObservableCollection<T>
    {

        /// <summary> 
        /// Adds the elements of the specified collection to the end of the ObservableCollection(Of T). 
        /// </summary> 
        public void AddRange(IEnumerable<T> collection)
        {
            foreach (var i in collection) Items.Add(i);
            OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, collection.ToList()));
        }

        /// <summary> 
        /// Removes the first occurence of each item in the specified collection from ObservableCollection(Of T). 
        /// </summary> 
        public void RemoveRange(IEnumerable<T> collection)
        {
            foreach (var i in collection) Items.Remove(i);
            OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, collection.ToList()));
        }

        /// <summary> 
        /// Clears the current collection and replaces it with the specified item. 
        /// </summary> 
        public void Replace(T item)
        {
            ReplaceRange(new T[] { item });
        }
        /// <summary> 
        /// Clears the current collection and replaces it with the specified collection. 
        /// </summary> 
        public void ReplaceRange(IEnumerable<T> collection)
        {
            List<T> old = new List<T>(Items);
            Items.Clear();
            foreach (var i in collection) Items.Add(i);
            OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, collection.ToList()));
        }

        /// <summary> 
        /// Initializes a new instance of the System.Collections.ObjectModel.ObservableCollection(Of T) class. 
        /// </summary> 
        public ObservableCollection() : base() { }

        /// <summary> 
        /// Initializes a new instance of the System.Collections.ObjectModel.ObservableCollection(Of T) class that contains elements copied from the specified collection. 
        /// </summary> 
        /// <param name="collection">collection: The collection from which the elements are copied.</param> 
        /// <exception cref="System.ArgumentNullException">The collection parameter cannot be null.</exception> 
        public ObservableCollection(IEnumerable<T> collection) : base(collection) { }
    }
}

I get this error now:

Additional information: Range actions are not supported.

The error comes here:

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

解决方案

A very quick and easy way is to subclass ObservableCollection and suspend notifications when AddRange is called. See the following blog post for clarification.

这篇关于我可以暂时禁用WPF数据绑定更改吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆