在ObservableCollection上实现INotifyPropertyChanged的目的是什么?

8

ObservableCollection实现了INotifyCollectionChangedINotifyPropertyChanged两个接口。

  • 我明白添加、删除(+清空)和替换项可以通过集合的事件CollectionChanged通知消费者,而现有项中的更新可以使用INotifyPropertyChanged自己实现的的事件PropertyChanged来监视。

  • 据我所知,你不能在集合的只读事件PropertyChanged上注册。

那么它的目的是什么,我们可以利用它做什么呢?

这里和那里的评论似乎让讨论变得混乱,暗示ObservableCollection的神奇之处在于实现了两个接口,允许同时通知集合和项内容的更改,但事实并非如此(很多示例都忽略了这一点,其中集合绑定到列表框后,当项内容更改时会自动更新,表明集合通知了列表框)。

实际上,似乎唯一的优势是实现了INotifyCollectionChanged。处理项属性更改似乎与其他集合一样困难:ObservableCollection只有在项实现INotifyPropertyChanged时才能实现,而它们可能没有这样做,并且如果用户设法独立于集合挂接到此事件,则可以实现。

这是正确的吗?

3个回答

9
如果您使用Reflector查看ObservableCollection<T>的源代码,您会发现此事件会为两个属性引发:

this.OnPropertyChanged("Count");
this.OnPropertyChanged("Item[]");

请注意,ObservableCollection<T> 显式实现了 INotifyPropertyChanged 接口,因此您只能通过 INotifyPropertyChanged 变量访问 PropertyChanged 事件:
INotifyPropertyChanged inpc = myObservableCollection;
inpc.PropertyChanged += myEventHandler;

虽然这个回答事实准确且简明扼要,但我不确定它如何回答Q中的“那么目的是什么?”部分。 - Andrew
2
目的是通知订阅者集合已更改。在这方面,它与CollectionChanged事件具有相同的目的,但INotifyPropertyChanged比INotifyCollectionChanged得到了更广泛的支持。 - Thomas Levesque

3

WPF的绑定机制可以直接使用INotifyPropertyChanged(INpc)。正如其名称所示,INpc允许WPF检测对象属性的更改,这些属性可能是集合的一部分,也可能不是。

ObservableCollection(OC)实现了INotifyCollectionChanged(InCC),就像你说的那样,集合本身会通知WPF(以及其他能够处理更新的人)其项集合的更新(添加、删除等)。如果OC包含的对象本身没有实现INpc,则WPF无法知道每个项的属性已更改。

更新

在回答以下问题“我们可以依赖于集合INpc事件而不是注册每个新项以获得通知吗?”时,答案是否定的。如果每个项在其属性上没有实现Inpc,则WPF无法知道每个项的值已更改。

WPF仍将从OC中知道项的部分添加或删除。Items属性使用INpc来通知更新,就像任何实现其属性上的INpc的类一样。InCC是用于跟踪集合更改而不是项内每个值的更改。


1
只是猜测:这样可以通知集合的 Count 属性发生变化吗?

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