簡體   English   中英

為什么ObservableCollection <T> 實現INotifyPropertyChanged?

[英]Why does ObservableCollection<T> implement INotifyPropertyChanged?

在.NET 4.0中,沒有ObservableCollection<T>定義的單個屬性,也沒有覆蓋其父級或接口的任何屬性。 那么,為什么ObservableCollection<T>實現INotifyPropertyChanged

我能想到的一個原因是,它使子類更容易定義自己的屬性並使用由ObservableCollection<T>實現的OnPropertyChanged方法。 但這是主要原因嗎?

同時通知CountItem[]更改。 這是一個示例(僅使用C#6進行字符串插值):

using System;
using System.ComponentModel;
using System.Collections.ObjectModel;

class Test
{
    static void Main(string[] args)
    {
        var collection = new ObservableCollection<string>();
        ((INotifyPropertyChanged)collection).PropertyChanged += (sender, e) =>
        {
            Console.WriteLine($"  {e.PropertyName} changed");
        };

        Console.WriteLine("Adding");
        collection.Add("Item");
        Console.WriteLine("Adding");
        collection.Add("Other item");
        Console.WriteLine("Removing");
        collection.RemoveAt(0);
        Console.WriteLine("Changing");
        collection[0] = "Different";
    }
}

輸出:

Adding
  Count changed
  Item[] changed
Adding
  Count changed
  Item[] changed
Removing
  Count changed
  Item[] changed
Changing
  Item[] changed

在屬性ItemItemsCount ,只有Item實際上有一個setter,因此無需覆蓋ItemsCount因為您無法設置它們,因此無需從中引發事件。 它們僅在響應某些其他方法(例如AddRemove )時發生更改,並且那些方法將引發必要的屬性更改事件(實際上,如果您查看源代碼, ObservableCollection<T>也不覆蓋這些方法,而是覆蓋protected基類中AddRemove調用的方法)。

現在,對於Item ,該屬性不會被覆蓋,但是如果您查看SetItem方法的源代碼

/// <summary>
/// Called by base class Collection&lt;T&gt; when an item is set in list;
/// raises a CollectionChanged event to any listeners.
/// </summary>
protected override void SetItem(int index, T item)
{
    CheckReentrancy();
    T originalItem = this[index];
    base.SetItem(index, item);

    OnPropertyChanged(IndexerName);
    OnCollectionChanged(NotifyCollectionChangedAction.Replace, originalItem, item, index);
}

您會從注釋中注意到,設置Item時,基類會調用此方法,並且還會觸發OnPropertyChanged事件。

如果查看Collection<T>來源 ,則可以確認是這種情況:

    public T this[int index] {
#if !FEATURE_CORECLR
        [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
#endif
        get { return items[index]; }
        set {
            if( items.IsReadOnly) {
                ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
            }

            if (index < 0 || index >= items.Count) {
                ThrowHelper.ThrowArgumentOutOfRangeException();
            }

            SetItem(index, value);
        }
    }

因此,總而言之, Collection<T> Item調用在ObservableCollection<T>中被覆蓋的SetItem ,這會觸發PropertyChanged事件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM