在ObservableCollection中,base.OnPropertyChanged("Item[]")是做什么的?

3

我在使用反编译器查看 ObservableCollection<T> 时发现了一些陌生的 OnPropertyChanged 代码,这让我感到好奇。

public class ObservableCollection<T> : Collection<T>, INotifyCollectionChanged, INotifyPropertyChanged
{    
    private const string IndexerName = "Item[]";

    protected override void ClearItems()
    {
        ...
        base.OnPropertyChanged("Count");
        base.OnPropertyChanged("Item[]");
        ...
    }
}

OnPropertyChanged("Item[]") 的调用是什么意思?如果我自己写代码,这个调用有什么帮助呢?

它一定比标准的OnPropertyChanged调用做了些不同的事情,因为'Item'不是对象上的属性,而 '[]'肯定也不是任何一个属性名称的一部分。


我非常确定这会通知绑定到集合的任何内容,表明项目已更改。 - N_A
如果您正在引用检测添加/删除的项目,则由INotifyCollectionChanged及其CollectionChanged事件处理。如果您要引用在集合中的项目上检测属性更改,则超出了ObservableCollection的范围。 - Kevin Kalitowski
1个回答

2
需要调用 OnPropertyChanged("Item[]") 方法来遵循 INotifyPropertyChanged 的精神。默认索引器 Item 返回的数据已经发生了变化。
在您的具体示例中,集合已被清空,因此如果要对集合中的某个特定项进行索引,则需要通知您感​​兴趣的对象引用可能已更改。

编辑

在 Kevin 的评论中提到绑定到索引器后,我编写了一个应用程序来测试绑定。
我创建了一个 ObservableCollection<int> 并像这样填充:
this.Indexed.Add(1);
this.Indexed.Add(2);
this.Indexed.Add(3);

如果你通过索引器绑定到像这样的内容,它将显示3:
<TextBlock Text="{Binding Indexed[2]}" />

然后在运行时更改该索引处的对象,

this.Indexed.Insert(2, 10);
将会更新并显示新的值 10

我认为我误解了如何使用索引器进行绑定。你是说如果你有<TextBox Text="{Binding MyObservableCollection[2]}" />,那么Text属性与ObservableCollection具有实时绑定,而不是直接绑定到该项本身?我从未这样想过,但这似乎表明,如果我进入代码并执行ObservableCollection.Insert(2, newItem),那么UI将更新并显示新项。如果经过深思熟虑,这是完全有道理的。 - Kevin Kalitowski
我不确定那个绑定是否会更新。我的主要想法是,如果它没有为Item属性引发事件,那么它就不会准确地实现INotifyPropertyChanged。 - davisoa
1
我刚刚编写了一个测试应用程序来查看会发生什么,你的绑定建议有效。我将编辑答案以包括重要的XAML。 - davisoa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接