2013-09-25 13 views
0

定制观察到的集合我已经实现了一个ObservableCollection支持大量添加像下面并绑定到一个WPF UI -用的AddRange&NotifyCollectionChangedAction.Add不工作

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,以便我可以观察变化。

任何人都可以请纠正我吗?

回答

2

如果您使用内部IList<T>添加它不会通知所有的事件,如使用AddAdd方法的工作原理是这样的项目,

  1. CheckReentrancy
  2. InsertItem
  3. OnPropertyChanged( “计数”);
  4. OnPropertyChanged(“Item []”);
  5. OnCollectionChanged(NotifyCollectionChangedAction.Add,item,index);

所以,如果你跳过添加方法,并直接添加项目到底层集合,你可能会得到这个炒锅。

实施例:(另)

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