父 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间通信详解

WPF MVVM 从 VIEW MODEL 获取父级

Android 调用组件 w/listener 或让 viewmodel 调用组件与片段通信

ViewModel学习