好的,我在XAML文件中有一个ItemsControl,它绑定到一个ObservableCollection。 ObservableCollection可以在视图模型类中找到(让我们调用这个类ViewModelA),ObservableCollection中的每个项都是另一个视图模型类的实例(让我们调用类ViewModelB)。 p>
ViewModelA上有一个属性,当更改时,间接更改在ViewModelB类的许多实例中找到的属性值。换句话说,它不会直接进入ViewModelB并设置其属性,从而导致INotifyPropertyChange调用,而是转到模型,在我的模型中设置一些属性,并且我的模型中的更改会影响ViewModelB应该显示的内容观点。
如何通知视图ViewModelB中的某些内容已更改?
答案 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的属性(模型类或其他任何人),如果属性有更改通知,视图将自动更新。