2012-03-24 35 views
2

我想要做的就是FreezableCollection.AddRange(collectionToAdd)我想要做的是FreezableCollection.AddRange(collectionToAdd)

每次我添加到的FreezableCollection引发事件和发生什么事。现在我有了一个新的集合,我想添加,但是这次我想让FreezableCollection的CollectionChanged事件只触发一次。

循环播放并添加它们会引发每个新项目的事件。

有没有一种方法可以将FreezableCollection全部添加到目标中,类似于List.AddRange?

+0

我很想知道我的答案是否对您有帮助。它似乎完全符合你的要求。 – 2012-03-24 21:46:58

+0

是的,它确实符合我的要求,但我希望有一个解决方案,不涉及子集的集合。也许是一种扩展方法...,这将在不改变Collection类型的情况下对实例起作用。谢谢。 – adentum 2012-03-24 22:00:28

+0

那么,代码如下。你可以在扩展方法中使用它。而不是重写,只需使用新的(扩展名)方法名称即可。 – 2012-03-24 22:05:39

回答

3

从集合中派生并覆盖您想要更改的行为。我能做到这一点是这样的:

public class PrestoObservableCollection<T> : ObservableCollection<T> 
    { 
     private bool _delayOnCollectionChangedNotification { get; set; } 

     /// <summary> 
     /// Add a range of IEnumerable items to the observable collection and optionally delay notification until the operation is complete. 
     /// </summary> 
     /// <param name="itemsToAdd"></param> 
     public void AddRange(IEnumerable<T> itemsToAdd) 
     { 
      if (itemsToAdd == null) throw new ArgumentNullException("itemsToAdd"); 

      if (itemsToAdd.Any() == false) { return; } // Nothing to add. 

      _delayOnCollectionChangedNotification = true;    

      try 
      { 
       foreach (T item in itemsToAdd) { this.Add(item); } 
      } 
      finally 
      { 
       ResetNotificationAndFireChangedEvent(); 
      } 
     } 

     /// <summary> 
     /// Clear the items in the ObservableCollection and optionally delay notification until the operation is complete. 
     /// </summary> 
     public void ClearItemsAndNotifyChangeOnlyWhenDone() 
     { 
      try 
      { 
       if (!this.Any()) { return; } // Nothing available to remove. 

       _delayOnCollectionChangedNotification = true; 

       this.Clear(); 
      } 
      finally 
      { 
       ResetNotificationAndFireChangedEvent(); 
      } 
     } 

     /// <summary> 
     /// Override the virtual OnCollectionChanged() method on the ObservableCollection class. 
     /// </summary> 
     /// <param name="e">Event arguments</param> 
     protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e) 
     { 
      if (_delayOnCollectionChangedNotification) { return; } 

      base.OnCollectionChanged(e); 
     } 

     private void ResetNotificationAndFireChangedEvent() 
     { 
      // Turn delay notification off and call the OnCollectionChanged() method and tell it we had a change in the collection. 
      _delayOnCollectionChangedNotification = false; 
      this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); 
     } 
    } 
+0

这是'ObservableCollection'的一个很好的例子,但'FreezableCollection'不公开'OnCollectionChanged'。 我仍然无法抑制FreezableCollections的更改通知。 – adentum 2012-03-25 00:58:21

+1

对不起,我没有意识到FreezableCollection是一个.NET类。我在想这是你创造的东西。所以,不,我没有你的答案。不过,我希望这里的总体思路仍然适用。 – 2012-03-25 01:11:39

0

跟进@ BobHorn的很好的答案,使之可与FreezableCollection

document

该成员是显式接口成员实施。它可以是 仅在FreezableCollection实例被强制转换为INotifyCollectionChanged接口时使用。

所以你可以通过演员来完成。

(FreezableCollection as INotifyCollectionChanged).CollectionChanged += OnCollectionChanged;