如何通知可观察集合中项目的属性已更改?

时间:2011-07-06 22:18:03

标签: c# wpf xaml observablecollection inotifypropertychanged

好的,我在XAML文件中有一个ItemsControl,它绑定到一个ObservableCollection。 ObservableCollection可以在视图模型类中找到(让我们调用这个类ViewModelA),ObservableCollection中的每个项都是另一个视图模型类的实例(让我们调用类ViewModelB)。 p>

ViewModelA上有一个属性,当更改时,间接更改在ViewModelB类的许多实例中找到的属性值。换句话说,它不会直接进入ViewModelB并设置其属性,从而导致INotifyPropertyChange调用,而是转到模型,在我的模型中设置一些属性,并且我的模型中的更改会影响ViewModelB应该显示的内容观点。

如何通知视图ViewModelB中的某些内容已更改?

4 个答案:

答案 0 :(得分:2)

您应该能够告诉View该集合已更改,然后触发它重新绑定到整个集合(这将更新视图)。

如果你的模型实现INotifyPropertyChanged,另一个选择是让你的ViewModelB类监听它包装模型的更改,并根据需要提升属性更改事件。

答案 1 :(得分:1)

理想情况下,你可以像Reed Copsey那样表示...在模型上实现INotifyPropertyChanged并让ViewModelB监听这些事件。然后,无论更新发生在何处,ViewModelB都会获取更改。

但是,在某些情况下,模型不会(或不能)实现INotifyPropertyChanged。在这种情况下,您可能需要考虑使用 Event Aggregator 模式在ViewModelA和ViewModelB实例之间传递消息。

在这种情况下,您可以从ViewModelA发布“模型已更改”消息。 ViewModelB实例将订阅此消息,并且当A发布消息时,每个实例都会收到通知。然后,ViewModelB可以引发适当的PropertyChanged事件,告诉UI发生了什么变化。

您可以在许多框架中找到有关Event Aggregator的更多信息,包括

答案 2 :(得分:0)

为了解决这个问题,我创建了一个名为VeryObservableCollection的类。对于您添加的每个对象,它将对象的NotifyPropertyChanged事件挂钩到触发CollectionChanged事件的处理程序。对于删除的每个对象,它将删除处理程序。很简单,会给你你想要的。部分代码:

public class VeryObservableCollection<T> : ObservableCollection<T>

/// <summary>
/// Override for setting item
/// </summary>
/// <param name="index">Index</param>
/// <param name="item">Item</param>
protected override void SetItem(int index, T item)
{
    try
    {
        INotifyPropertyChanged propOld = Items[index] as INotifyPropertyChanged;
        if (propOld != null)
            propOld.PropertyChanged -= new PropertyChangedEventHandler(Affecting_PropertyChanged);
    }
    catch (Exception ex)
    {
        Exception ex2 = ex.InnerException;
    }
    INotifyPropertyChanged propNew = item as INotifyPropertyChanged;
    if (propNew != null)
        propNew.PropertyChanged += new PropertyChangedEventHandler(Affecting_PropertyChanged);

    base.SetItem(index, item);
}

答案 3 :(得分:0)

如果模型中的更改将在ViewModelB的某些属性中更改,并且这些属性具有对UI的更改通知(即ViewModleB正在实现INotifyPropertyChanged),则更改将立即反映在UI中。

因此,如果您有另一个viewmodelB的ObservableCollection,则无需为该viewmodelB的propertychanged挂钩事件。根据我的理解,无论谁更改viewmodelB的属性(模型类或其他任何人),如果属性有更改通知,视图将自动更新。