C# 在父视图模型中公开子视图模型的属性
我的父视图模型包含两个子视图模型,它看起来像C# 在父视图模型中公开子视图模型的属性,c#,wpf,mvvm,C#,Wpf,Mvvm,我的父视图模型包含两个子视图模型,它看起来像 public MainViewModel:ObservableObject { public MainViewModel(){//initalize everything}; private SomeViewModel childvm1; private AnotherViewModel childvm2; public SomeViewModel Childvm1 {
public MainViewModel:ObservableObject
{
public MainViewModel(){//initalize everything};
private SomeViewModel childvm1;
private AnotherViewModel childvm2;
public SomeViewModel Childvm1
{
get
{
return childvm1;
}
set
{
SetField(ref childvm1, value, "Childvm1");
}
}
public AnotherViewModel Childvm2
{
get
{
return childvm2;
}
set
{
SetField(ref childvm2, value, "Childvm2");
}
}
//when this changes i want to notify childvm2 and call a function in it
public SomeModel SelectedValueofChildvm1
{
get
{
return Childvm1.SelectedValue;
}
}
}
当
SelectedValueofChildvm1
更改时,如何调用childvm2
中的函数?您必须订阅子视图模型的PropertyChangedEvent,如下所示:
public SomeViewModel Childvm1
{
get
{
return childvm1;
}
set
{
if (childvm1 != null) childvm1.PropertyChanged -= OnChildvm1PropertyChanged;
SetField(ref childvm1, value, "Childvm1");
if (childvm1 != null) childvm1.PropertyChanged += OnChildvm1PropertyChanged;
}
}
private coid OnChildvm1PropertyChanged(object sender, PropertyChangedEventArgs e)
{
// now update Childvm2
}
但要小心:
- 您可能还需要在childvm2 setter中更新childvm2
- 您需要确保childvm1实例不超过ViewModel实例,或者在将MainViewModel返回给垃圾收集器之前,将childvm1设置为null
INotifyPropertyChanged
界面来侦听属性更改通知
public MainViewModel:ObservableObject
{
public MainViewModel(){
//initalize everything
Childvm1.PropertyChanged += (s,e) {
if(e.PropertyName == "SelectedValue") {
// Do what you want
}
};
};
}
SelectedValueofChildvm1
如何改变,当没有set
时?集合在childvm1中,我也必须在这里公开它吗?你需要对值的变化做出反应,还是你只是想让它可以绑定?@CodingGorilla我需要对它的变化做出反应所以,假设视图模型实现了INotifyPropertyChanged
(错误的假设),只需将处理程序附加到PropertyChanged
,并在属性更改时做出反应。这不管用吗?如果您希望子视图模型发生变化,那么这很好,如果不是,那么我的方法就简单多了。=)显然,OP希望它们发生变化,因为包含了Childvm1属性的公共setter。另外,我不知道为什么您的解决方案比这个简单得多?您没有取消订阅活动,因此您的代码少了一行,这是真的。但在这个解决方案中,订阅和取消订阅是非常对称的,它们所属的属性也很好,不那么脆弱。这不是批评,我的观点是,如果他不希望它发生变化,那么在构造函数中连接处理程序就更简单了,这样就完成了。我们看不到设置字段
的作用,因此它完全有可能处理属性更改通知,但不允许更改特定字段(如子视图模型)。@CodingGorilla我没有将您的评论视为批评,只是讨论它以便我们和其他读者能够了解。事实上,每当我有一个只读
字段(因此属性中没有setter)时,我自己就使用您的方法。当字段不是只读字段时,我在属性中有一个setter(可能是私有的,也可能是公共的),并在其中包含代码。关于SetField,您是对的,但我假设它是从observeObject继承的样板代码“if it change raise the event”。