You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将INotifyCollectionChanged的变更同步到另一个集合?

同步两个ObservableCollection的变更:解决方案

.NET(包括.NET 6及后续版本)没有内置能直接接收NotifyCollectionChangedEventArgs并同步变更的Apply方法,你需要自行实现变更同步逻辑。

实现建议:编写扩展方法

可以为ObservableCollection<T>编写一个扩展方法,完整处理NotifyCollectionChangedEventArgs中的所有操作类型,避免手动重复判断:

using System.Collections.ObjectModel;
using System.Collections.Specialized;

public static class ObservableCollectionExtensions
{
    public static void ApplyCollectionChange<T>(this ObservableCollection<T> target, NotifyCollectionChangedEventArgs args)
    {
        switch (args.Action)
        {
            case NotifyCollectionChangedAction.Add:
                if (args.NewItems != null)
                {
                    foreach (T item in args.NewItems)
                    {
                        target.Insert(args.NewStartingIndex, item);
                    }
                }
                break;
            case NotifyCollectionChangedAction.Remove:
                if (args.OldItems != null)
                {
                    foreach (T item in args.OldItems)
                    {
                        target.Remove(item);
                    }
                }
                break;
            case NotifyCollectionChangedAction.Replace:
                if (args.OldItems != null && args.NewItems != null)
                {
                    for (int i = 0; i < args.OldItems.Count; i++)
                    {
                        int index = args.OldStartingIndex + i;
                        if (index >= 0 && index < target.Count)
                        {
                            target[index] = (T)args.NewItems[i];
                        }
                    }
                }
                break;
            case NotifyCollectionChangedAction.Move:
                if (args.NewItems != null && args.NewItems.Count == 1)
                {
                    T item = (T)args.NewItems[0];
                    target.RemoveAt(args.OldStartingIndex);
                    target.Insert(args.NewStartingIndex, item);
                }
                break;
            case NotifyCollectionChangedAction.Reset:
                target.Clear();
                if (args.NewItems != null)
                {
                    foreach (T item in args.NewItems)
                    {
                        target.Add(item);
                    }
                }
                break;
        }
    }
}

使用示例

将你原来的代码修改为调用这个扩展方法即可:

ObservableCollection<int> A = new ObservableCollection<int>();
ObservableCollection<int> B = new ObservableCollection<int>();

A.CollectionChanged += (s, args) =>
{
    B.ApplyCollectionChange(args);
};

A.Add(1);
A.Add(2);
// 此时B包含1和2,与A完全同步

注意事项

  • 该方法处理了所有标准的NotifyCollectionChangedAction类型,包括批量添加/删除、移动、替换和重置操作
  • 如果集合包含引用类型,同步的是对象引用,若需要深拷贝需额外处理
  • 若在UI线程中使用,确保同步操作在UI上下文执行(WPF/WinUI场景下可通过Dispatcher调度)

内容的提问来源于stack exchange,提问作者Batesias

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 12:55:37