CollectionChanged事件

时间:2012-02-20 05:04:53

标签: c# observablecollection

ObservableCollection提供CollectionChanged事件,我们在列表中添加,删除或更新项目,但它会针对单个项目更改引发事件,例如,每当我将新项目添加到它集合了它的集合。

现在,我想要的是在完成对集合的所有修改后引发事件,例如,我需要添加2个项目,删除一个项目并更新2个项目。 CollectionChanged事件只应在完成所有这些添加,删除和更新后触发。

或者,假设我有一个包含所有修改的新集合,现在,我想在分配新集合时引发CollectionChanged,例如:

ObservableCollection<string> mainCollection; //assume it has some items 
mainCollection = updatedCollection; // at this point I want to raise the event.

请提供宝贵的建议。

此致

BHavik

3 个答案:

答案 0 :(得分:2)

它不会像你编写的那样工作,原因是你已经订阅了mainCollection对象的事件,然后用另一个对象替换它,只是用相同的变量名称来引用它。您无需分配集合,只需将更新集合的所有元素添加到主集合

修改 AddLogge for ObservableCollection:

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

namespace System.Collections.ObjectModel
{

/// <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));
    }

    /// <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) { }
}
}

取自this question

答案 1 :(得分:1)

看起来您更愿意看到对mainCollection变量的赋值,而不是发出ObservableCollection类的事件。像这样:

        private ObservableCollection<MyItemType> _mainCollection;
        public ObservableCollection<MyItemType> MainCollection
        {
            get
            {
                return _mainCollection;
            }
            set
            {
                _mainCollection = value;
                TriggerMyEvent(); // do whatever you like here
            }
        }

答案 2 :(得分:1)

标准ObservableCollection<T>不支持此方案。您可以使用所需的逻辑创建一个实现INotifyCollectionChanged接口的类,例如,使用单个方法将所有项替换为另一个集合。

对于UI可能不太好,例如,如果选择或聚焦了一个集合绑定元素,如果完全重新初始化集合,这个状态将会丢失。取决于你的情况。