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

4
好的,我在XAML文件中有一个ItemsControl,它绑定到一个ObservableCollection。这个ObservableCollection可以在一个视图模型类(我们称之为ViewModelA)中找到,而ObservableCollection中的每个项目都是另一个视图模型类(我们称之为ViewModelB)的实例。
ViewModelA有一个属性,在更改时会间接地更改ViewModelB类许多实例中的属性值。换句话说,它不直接去设置ViewModelB的属性,从而导致INotifyPropertyChange调用,而是进入模型,设置一些模型属性,该模型属性影响了ViewModelB应该在视图中显示什么。
如何通知视图ViewModelB中的内容已经发生了变化?
4个回答

2

你应该能够告诉视图集合已经发生了变化,进而触发它重新绑定整个集合(这将更新视图)。

如果你的模型实现了INotifyPropertyChanged接口,另一个选择是让你的ViewModelB类监听其包装的模型的更改,并在需要时引发属性更改事件。


+1;你的回答比问题更清晰,所以我会重申一般情况:通知视图变化的两种方法是“INotifyCollectionChanged”和“INotifyPropertyChanged”。但是,如果您的视图模型相互依赖,则在视图模型中使用这些接口并根据需要向上冒泡通知也是完全自然的。 - Merlyn Morgan-Graham
1
关键在于集合本身没有改变,因此 INotifyCollectionChanged 对我没有用。但是,我可以在我的模型类上实现 INotifyPropertyChanged,所以看起来这将起作用。感谢您的帮助! - David

1
理想情况下,您可以像Reed Copsey所示那样...在模型上实现INotifyPropertyChanged,并使ViewModelB监听这些事件。然后,无论更新发生在哪里,ViewModelB都会捕获更改。
但是,在某些情况下,模型不会(或无法)实现INotifyPropertyChanged。在这种情况下,您可能需要考虑使用“事件聚合器”模式在ViewModelA和ViewModelB实例之间传递消息。
在这种情况下,您可以从ViewModelA发布“模型已更改”的消息。 ViewModelB实例将订阅此消息,并在A发布消息时通知它们中的每一个。然后,ViewModelB可以引发适当的PropertyChanged事件,以告诉UI发生了什么变化。
您可以在许多框架中找到有关事件聚合器的更多信息,包括...

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);
}

0

如果在Models中进行更改会影响到ViewModelB的某些属性,并且这些属性具有通知UI的更改(即ViewModleB实现了INotifyPropertyChanged),则更改将立即反映在UI中。

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


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