集合更改事件

发布于 2025-01-07 12:43:09 字数 557 浏览 0 评论 0原文

当我们从集合中添加、删除或更新项目时,ObservableCollection 提供 CollectionChanged 事件,但它会引发单个项目更改的事件,例如,每当我添加新项目时项目到集合它引发集合。

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

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

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

请提供您的宝贵建议。

问候,

巴维克

ObservableCollection provides the CollectionChanged event whenevet we add, remove or update the item from the colleciton, but it raises the event for individual item change, for example, whenever I add the new item to the collection it raises the collection.

Now, what I want is to raise the event after completing all the modifications to the collection, for example, I need to add 2 items, delete one item and update 2 items. The CollectionChanged event should only fire after completiong all these add, delete and update.

Or, suppose I have a new collection with all the modifications, now , i want to raise the CollectionChanged when I assign the new collection, for example:

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

Please provide your valuable suggestions.

Regards,

BHavik

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

┊风居住的梦幻卍 2025-01-14 12:43:09

看起来您宁愿观看对 mainCollection 变量的赋值,而不是观察触发 ObservableCollection 类的事件。像这样的事情:

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

Looks like you'd rather be watching assignment to the mainCollection variable rather than the events that fire off the ObservableCollection class. Something like this:

        private ObservableCollection<MyItemType> _mainCollection;
        public ObservableCollection<MyItemType> MainCollection
        {
            get
            {
                return _mainCollection;
            }
            set
            {
                _mainCollection = value;
                TriggerMyEvent(); // do whatever you like here
            }
        }
无尽的现实 2025-01-14 12:43:09

它不会按照您编写的方式工作,原因是您已经订阅了 mainCollection 对象的事件,然后将其替换为整个另一个对象,只是通过相同的变量名称引用它。您不需要分配集合,而是将更新集合的所有元素添加到主集合

编辑:
ObservableCollection 的 AddRange:

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

取自这个问题

It won't work the way you written, the cause is that you've subscribed to event of mainCollection object and then replace it with whole another object just referencng it by the same variable name. You need not to assign collection but to add all elements of updated collection to main collection

EDIT:
AddRange 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) { }
}
}

Taken from this question

—━☆沉默づ 2025-01-14 12:43:09

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

这可能对 UI 不利,例如,如果选择了集合绑定元素或聚焦了该元素,则如果您完全重新初始化集合,则此状态将丢失。取决于你的场景。

Standard ObservableCollection<T> doesn't support this scenario. You can create a class implementing INotifyCollectionChanged interface with the logic you need, for example, with a single method to substitute all items with another collection.

That might not be good for UI, for example, if a collection-bound element was selected or focused this state will be lost if you completely re-initialize the collection. Depends on your scenario.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文