ObservableCollection Doesn't support AddRange method, so I get notified for each item added, besides what about INotifyCollectionChanging?

前端 未结 12 1446
走了就别回头了
走了就别回头了 2020-11-22 16:19

I want to be able to add a range and get updated for the entire bulk.

I also want to be able to cancel the action before it\'s done (i.e. collection changing besides

12条回答
  •  傲寒
    傲寒 (楼主)
    2020-11-22 16:47

    Proof of need for OnPropertyChanged("Count") and OnPropertyChanged("Item[]") calls in order to behave as per ObservableCollection. Note that I don't know what the consequences are if you don't bother!

    Here is a test method that shows that there are two PropertyChange events for each add in a normal observable collection. One for "Count" and one for "Item[]".

    [TestMethod]
    public void TestAddSinglesInOldObsevableCollection()
    {
      int colChangedEvents = 0;
      int propChangedEvents = 0;
      var collection = new ObservableCollection();
      collection.CollectionChanged += (sender, e) => { colChangedEvents++; };
      (collection as INotifyPropertyChanged).PropertyChanged += (sender, e) => { propChangedEvents++; };
      collection.Add(new object());
      collection.Add(new object());
      collection.Add(new object());
      Assert.AreEqual(3, colChangedEvents);
      Assert.AreEqual(6, propChangedEvents);
    }
    
    
    

    @Shimmy , swap the standard for your collection and change to an add range and you will get zero PropertyChanges. Note that collection change does work fine, but not doing exactly what ObservableCollection does. So Test for shimmy collection looks like this:

    [TestMethod]
    public void TestShimmyAddRange()
    {
      int colChangedEvents = 0;
      int propChangedEvents = 0;
      var collection = new ShimmyObservableCollection();
      collection.CollectionChanged += (sender, e) => { colChangedEvents++; };
      (collection as INotifyPropertyChanged).PropertyChanged += (sender, e) => { propChangedEvents++; };
      collection.AddRange(new[]{
        new object(), new object(), new object(), new object()}); //4 objects at once
      Assert.AreEqual(1, colChangedEvents);  //great, just one!
      Assert.AreEqual(2, propChangedEvents); //fails, no events :(
    }
    
    
    

    FYI here is code from InsertItem (also called by Add) from ObservableCollection:

    protected override void InsertItem(int index, T item)
    {
      base.CheckReentrancy();
      base.InsertItem(index, item);
      base.OnPropertyChanged("Count");
      base.OnPropertyChanged("Item[]");
      base.OnCollectionChanged(NotifyCollectionChangedAction.Add, item, index);
    }
    

    提交回复
    热议问题