我有一个嵌套的视图模型结构,如下例所示:
public class SubViewModel : INotifyPropertyChanged
{
public string Property
{
get
{
// calculate result and return it
}
}
}
public class ViewModel : INotifyPropertyChanged
{
public SubViewModel Sub { get; set; }
public void MyMethod()
{
// executes code that changes some parameters such that Sub.Property changes
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Sub.Property"));
}
}
在父视图模型中发生更改会影响嵌套视图模型的属性。换句话说,子视图模型上的属性(示例中为SubViewModel.Property
)会更改,但子视图模型不会知道。
我希望以告诉WPF绑定引擎的方式调用PropertyChanged
子视图模型Property
上的属性Sub
已更改。我尝试了以下所有选项,但到目前为止还没有任何选项:
OnPropertyChanged("");
OnPropertyChanged("*");
OnPropertyChanged("Sub");
OnPropertyChanged("Sub.Property");
OnPropertyChanged("Sub.*");
有没有办法实现这个目标?
请注意:我知道父视图模型可以在子视图模型上调用一个方法,该方法在子视图模型上引发PropertyChanged
事件。我有理由不这样做。
答案 0 :(得分:0)
在SubView中,您必须绑定如下属性: “Example = {Binding MyProperty}”
public class SubViewModel : INotifyPropertyChanged
{
private string _MyProperty;
public string MyProperty
{
get { return _MyProperty; }
set { _MyProperty = value;
NotifyPropertyChanged();
}
}
#region NotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] string info = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(info));
}
#endregion
}
public class ViewModel : INotifyPropertyChanged
{
private SubViewModel _Sub;
public SubViewModel Sub
{
get { return _Sub; }
set { _Sub = value;
NotifyPropertyChanged();
}
}
public void MyMethod()
{
// executes code that changes some parameters such that Sub.Property changes
NotifyPropertyChanged();
}
#region NotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] string info = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(info));
}
#endregion
}
答案 1 :(得分:0)
您正在ViewModel
和SubViewModel
之间创建循环依赖关系。这导致两者之间的强耦合,这从来都不是好事。我提出了另一种解决方案。 INotifyPropertyChanged
已经为基础设施提供了您想要的功能。
因此SubViewModel
依赖于ViewModel
。我认为它需要ViewModel
的一个属性的值来计算SubViewModel.Property
的值。因此,解决方案很自然地将SubViewModel
与ViewModel.PropertyChanged
联系起来:
public class SubViewModel : INotifyPropertyChanged
{
private ViewModel parent;
public event PropertyChangedEventHandler PropertyChanged;
public SubViewModel(ViewModel parent)
{
this.parent = parent;
// Hook up to parent's property changes.
this.parent.PropertyChanged += (sender, e) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("SubProperty"));
}
public string SubProperty
{
get { return parent.Property; }
}
}
注意如何在ViewModel
的construcor中期望SubViewModel
来明确依赖关系。这样,下一个程序员立即看到SubViewModel
需要ViewModel
才能正常工作,并且无法构建无效的SubViewModel
。
构造函数中定义的事件处理程序当然非常简化。最好使它成为一个私有方法,在它执行任何操作之前检查e.PropertyName
。无论如何,它的基本目的是通知所有订阅SubViewModel
属性更改的客户,因为ViewModel.Property
已经更改了。{/ p>
您最好没有从ViewModel
到SubViewModel
的关系,以避免循环依赖。摆脱Sub
属性并实现ViewModel
,如下所示:
public class ViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string property;
public string Property
{
get { return this.property; }
set
{
this.property = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Property"));
}
}
}
请注意ViewModel
的实现与任何其他INotifyPropertyChanged
实现完全相同。父母不需要知道孩子的价值观。只有ViewModel
的客户端实现处理ViewModel
属性更改的逻辑,不父级。
以下是测试的工作示例:https://dotnetfiddle.net/vQJBak
答案 2 :(得分:0)
在SubViewModel
中创建一个事件,并在发生变化时引发该事件。父视图模型将订阅该事件。
这是什么事件。