0

我已经实现了一个 ObservableCollection 来支持像下面这样的批量添加并绑定到 WPF UI -

public void  AddRange(IEnumerable<T> list)
        {
            lock (_lock)
            {
                if (list == null)
                {
                    throw new ArgumentNullException("list");
                }

                _suspendCollectionChangeNotification = true;
                var newItems = new List<T>();

                foreach (T item in list)
                {
                    if (!Contains(item))
                    {
                        Add(item);
                        newItems.Add(item);
                    }
                }
                _suspendCollectionChangeNotification = false;

                var arg = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, newItems);
                OnCollectionChanged(arg);  //NotifyCollectionChangedAction.Reset works!!!
            }
        }
    }

    public override event NotifyCollectionChangedEventHandler CollectionChanged;

            protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
            {
                NotifyCollectionChanged(e);
            }

            internal void NotifyCollectionChanged(NotifyCollectionChangedEventArgs e)
            {
                if (IsCollectionChangeSuspended)
                {
                    return;
                }

                NotifyCollectionChangedEventHandler handler = CollectionChanged;
                if (handler != null)
                {
                    if (Application.Current != null && !Application.Current.Dispatcher.CheckAccess())
                    {
                        Application.Current.Dispatcher.Invoke(DispatcherPriority.DataBind,handler, this, e);
                    }
                    else
                    {
                        handler(this, e);
                    }
                }
            }

    private bool IsCollectionChangeSuspended
    {
        get { return _suspendCollectionChangeNotification; }
    }

我收到此错误 - {“集合已修改;枚举操作可能无法执行。”}

但是,如果我更改NotifyCollectionChangedAction.AddNotifyCollectionChangedAction.Reset并且不传递任何更改的列表,那么它会正确绑定到 UI。但是,我想使用NotifyCollectionChangedAction.Add这样我可以观察到变化。

谁能纠正我?

4

1 回答 1

2

如果您使用内部IList<T>添加项目,它不会通知所有事件,如使用Add方法,

Add方法的工作原理如下:

  1. 检查重入
  2. 插入项
  3. OnPropertyChanged("计数");
  4. OnPropertyChanged("项目[]");
  5. OnCollectionChanged(NotifyCollectionChangedAction.Add, item, index);

因此,如果您跳过 Add 方法并将项目直接添加到基础集合中,您可能会得到它。

示例:(未经测试)

public void AddRange(IEnumerable<T> rangeItems)
{
    foreach (var item in rangeItems)
    {
         Items.Add(item);
    }

            base.OnPropertyChanged(new PropertyChangedEventArgs("Count"));
            base.OnPropertyChanged(new PropertyChangedEventArgs("Item[]"));
            var arg = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, rangeItems);
            OnCollectionChanged(arg);
}
于 2013-09-25T21:42:41.677 回答