WPF中为List<>属性添加PropertyChanged通知不生效的原因是什么?
底层原因分析
1. 两种不同的变更通知场景
WPF的UI更新依赖两类完全独立的变更通知接口,作用边界清晰:
INotifyPropertyChanged:负责通知属性本身的引用/值发生了替换,仅当属性的setter被调用时才会触发你代码里写的PropertyChanged事件。INotifyCollectionChanged:负责通知集合类型属性指向的实例内部元素发生了变更(增、删、修改、清空等操作),和属性本身的引用是否变化无关。
2. List不生效的直接原因
你代码中点击按钮的操作是对已经存在的List实例执行Clear、Add操作,全程没有调用Items属性的setter,所以写在setter里的PropertyChanged事件根本不会触发,UI自然感知不到集合内部的变化。
验证:如果你在按钮操作的末尾添加一行
Items = Items;强制触发setter执行,UI也会同步更新,只是这种方式性能远不如专门的集合通知机制。
3. ObservableCollection生效的原因
ObservableCollection<T>在.NET的原生实现里已经默认实现了INotifyCollectionChanged接口,每次集合内部执行增删改、清空操作时,都会自动抛出CollectionChanged事件。WPF的ListBox、ItemsControl等集合控件绑定数据源时,会自动监听数据源的INotifyCollectionChanged事件,只要收到事件就会立刻刷新UI展示,不需要修改集合本身的引用。
4. String类型生效的本质原因
String是.NET中的不可变类型,任何对String值的修改都会生成一个全新的String实例,必然会触发属性的setter执行,进而触发INotifyPropertyChanged通知,所以看起来修改String属性就会自动更新UI。
内容的提问来源于stack exchange,提问作者lixiangc
相关产品推荐
相关产品推荐

