父 ViewModel 与子通信
Posted
技术标签:
【中文标题】父 ViewModel 与子通信【英文标题】:Parent ViewModel communicate child 【发布时间】:2017-03-14 22:47:51 【问题描述】:我有一个带有嵌套子视图的主视图。我有一个包含子 VM 实例的主 VM。 在某些时候,主虚拟机需要与子虚拟机交互。
在主虚拟机中。我将子 ViewModel 定义为
public ChildViewModel VmChild
get
if (this.vmChild == null)
this.vmChild = new ChildViewModel();
return this.vmChild;
set
if (this.vmChild != value)
this.vmChild = value;
this.OnPropertyChanged("VmChild");
在主视图中。我有
<StackPanel Orientation="Vertical" HorizontalAlignment="Left" >
<localViews:ChildView DataContext="Binding VmChild"> </localViews:ChildView>
</StackPanel>
在子视图代码后面。
public ChildViewModel ViewModel
get
if (this.vmChild == null)
this.vmChild = new ChildViewModel();
return this.vmChild;
set
if (this.vmChild != value)
this.vmChild = value;
和
private void InitializeViewModel()
if (this.DataContext is ChildViewModel)
this.ViewModel = this.DataContext as ChildViewModel;
else
this.DataContext = this.ViewModel;
我的问题是我的代码有效。但是当我打开主视图时它有一个例外。
例外是NullReferenceException was thrown on "ChildView": Cannot create an instance of "ChildView"
。错误行在this.vmChild = new ChildViewModel();
我认为我定义了两次视图模型实例来导致它。在主视图模型中,我已经定义了子 vm 实例。在子视图后面的代码中,我再次定义了它。但我不知道如何解决它。
编辑:
【问题讨论】:
错误行位于this.vmChild = new ChildViewModel();
,但您有其中两行。这本身就很奇怪。
如果您不告诉我们第 82 行的内容,那张图片将无济于事。但看起来问题可能出在构造函数内部。
第 82 行似乎不敬。这是一个捕获部分代码。现在错误变为“灾难性故障(来自 HRESULT 的异常:0x8000FFFF (E_UNEXPECTED))”。问题是我使用你的代码。 DataContext
为空。原因是代码首先到达了 getter。它尚未在 ViewModel 中分配值。
那么您的代码或绑定应该对空值更具弹性。通过移除部件来查找问题,直到错误消失。
【参考方案1】:
您正在尝试“修复”不应该发生或不应该发生的空值场景。
删除孩子的代码隐藏部分,如果你真的需要一个 ViewModel 属性(这是 UWP 的吗?),使用这个:
// not normally needed in WPF/MVVM
public ChildViewModel ViewModel get return DataContext as ChildViewModel;
子视图获取一个 ViewModel,它不应该创建一个。
【讨论】:
这是一个银光项目。我还需要二传手吗?我在 Visual Studio 2010 中使用 .NET 4。似乎需要 setter。 不,您正在设置 DataContext。 ViewModel 不需要 setter。 但据我所知,C# 4.0 需要 getter 和 setter 一起使用,除非使用 C# 6。而且错误仍然存在。 C#1 可以不用设置器。【参考方案2】:在主视图中替换
DataContext="Binding VmEChild
与
DataContext="Binding VmChild
【讨论】:
对不起,这是问题中的错字。我重新编辑它。这不是真正的原因。 问题代码不能有错别字。始终从实际代码中复制/粘贴。以上是关于父 ViewModel 与子通信的主要内容,如果未能解决你的问题,请参考以下文章
无法使用数据绑定Android与ViewModel中的XML通信
SwiftUI 中 ViewModel + View 之间的通信
Android ViewModel+LiveData实现Fragment间通信详解