【发布时间】:2012-02-10 08:09:18
【问题描述】:
我有一个 MVVM 风格的应用程序。那里有一个自定义控件,其依赖属性持有 A 的 ObservableCollection。A 有 B 的 ObservableCollection。A 和 B 实现 INotifyPropertyChanged。
当我在 ViewModel 中将 B 的对象添加到 A 时,更改不会传播到控件。 xaml 中的绑定是正确的,因为显示的是 B,Mode 是 TwoWay。
【问题讨论】:
我有一个 MVVM 风格的应用程序。那里有一个自定义控件,其依赖属性持有 A 的 ObservableCollection。A 有 B 的 ObservableCollection。A 和 B 实现 INotifyPropertyChanged。
当我在 ViewModel 中将 B 的对象添加到 A 时,更改不会传播到控件。 xaml 中的绑定是正确的,因为显示的是 B,Mode 是 TwoWay。
【问题讨论】:
这是正常行为,因为控件只监听INotifyPropertyChanged 而不是ICollectionChanged。集合属性本身不会改变,因此控件不知道它必须刷新。
为了将集合更改传递给控件,您必须订阅ObservableCollection 的CollectionChanged 事件,然后在集合更改时引发集合属性的属性更改事件(添加的项目,已移除、移动或集合被清除)。
#region [BViewModelCollection]
/// <summary>
/// The <see cref="BViewModelCollection" /> property's name.
/// </summary>
public const string BViewModelCollectionPropertyName = "BViewModelCollection";
private ObservableCollection<BViewModel> _bViewModelCollection = new ObservableCollection<BViewModel>();
/// <summary>
/// Gets the BViewModelCollection property.
/// TODO Update documentation:
/// Changes to that property's value raise the PropertyChanged event.
/// This property's value is broadcasted by the Messenger's default instance when it changes.
/// </summary>
public ObservableCollection<BViewModel> BViewModelCollection {
get {
return _bViewModelCollection;
}
set {
if (_bViewModelCollection != value) {
SetBViewModelCollection(value);
RaisePropertyChanged(BViewModelCollectionPropertyName);
}
}
}
private void SetBViewModelCollection(ObservableCollection<BViewModel> value) {
if (_bViewModelCollection != null)
_bViewModelCollection.CollectionChanged -= this.BViewModelCollection_CollectionChanged;
_bViewModelCollection = value;
if (_bViewModelCollection != null)
_bViewModelCollection.CollectionChanged += this.BViewModelCollection_CollectionChanged;
}
private void BViewModelCollection_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) {
RaisePropertyChanged(BViewModelCollectionPropertyName);
}
#endregion
您现在可以使用 SetBViewModelCollection 设置 ObservableCollection 并自动正确注册事件,而无需为集合引发 PropertyChanged 事件 - 例如用于构造函数或加载数据方法。
当一个项目现在添加到集合中或从集合中删除时,您的控件应该会收到集合属性已更改的通知。
注意:将方法名称调整为您自己的框架。
【讨论】: