当ItemsControl.ItemsSource发生更改时,是什么触发了UI的更新?
当ItemsControl.ItemsSource发生更改时,是什么触发了UI的更新?
我刚刚在查阅这个问题后,研究了BindingList和ObservableCollection之间的区别:为什么在WPF中不使用BindingList。
作为其中的一部分,我尝试将ItemsControl的ItemsSource绑定到不同类型,包括List、Collection、ObservableCollection和BindingList。
让我惊讶的是,当修改ObservableCollection或BindingList时,界面会更新,而修改其他类型时则不会。那么WPF是通过监听什么来实现这种更新的呢?正如我之前所认为的那样,它不可能是INotifyCollectionChanged事件,因为BindingList并没有实现它。感到困惑。
当ItemsControl.ItemsSource改变时,UI更新的触发机制是什么?这个问题的出现的原因是,WPF中的ItemsControl实际上是通过订阅BindingList的ListChanged事件来实现UI的更新的。具体来说,当ItemsSource绑定的是一个实现了IBindingList接口的集合类时,WPF会创建一个BindingListCollectionView来包装这个集合类,并订阅这个集合类的ListChanged事件。这样,当集合类的数据发生改变时,BindingListCollectionView就会收到ListChanged事件的通知,从而触发UI的更新。
解决这个问题的方法是使用DotPeek这个工具来查看WPF的源代码,通过查看DotPeek的反编译结果,可以看到WPF是如何处理ItemsControl.ItemsSource的改变以及UI的更新的。通过查看源代码,可以发现WPF在处理ItemsControl.ItemsSource的改变时,会创建一个BindingListCollectionView来包装集合类,并订阅集合类的ListChanged事件。这样,当集合类的数据发生改变时,BindingListCollectionView就会收到ListChanged事件的通知,从而触发UI的更新。
总结起来,WPF通过订阅BindingList的ListChanged事件来实现UI的更新。当ItemsControl.ItemsSource绑定的是一个实现了IBindingList接口的集合类时,WPF会创建一个BindingListCollectionView来包装这个集合类,并订阅这个集合类的ListChanged事件。这样,当集合类的数据发生改变时,BindingListCollectionView就会收到ListChanged事件的通知,从而触发UI的更新。