首页 > 解决方案 > WPF MVVM:如何避免创建 ViewModel 的多个实例?

问题描述

我正在使用 MVVM 编写一个多页 WPF 应用程序,但我遇到了一个似乎无法有效解决的问题。如果应用程序中的任何时候出现错误,我创建了单个子视图,可以在视图中显示以在任何页面(视图)上显示错误和信息。

我试图这样做的方式是:

  1. 页面(视图)有一个 ViewModel 来处理业务逻辑,包括确定出现问题。然后它将在将显示错误的内容控件中创建错误子视图的实例。
  2. ViewModel 通过调用 Sub-View 的 ViewModel 上的公共方法来指示发生了哪个错误,并向该函数传递一个字节索引,以便 Error Sub-View 可以查找并获取要显示的信息。
  3. Sub-ViewModel 在属性“ActiveError”中设置此错误信息。ActiveError 有一个 RaisePropertyChanged 方法,错误子视图有绑定到这个属性的文本字段来显示数据。

简单的东西。但是,错误子视图会显示,但不会显示任何数据。

我以为我通过将 ActiveError 设为静态来解决这个问题,直到我弄清楚到底发生了什么(我认为)。未显示 ActiveError 数据,因为在此过程中,正在创建 3 个 Error Sub-ViewModel 实例。

一个是在我们创建 Sub-ViewModel 时创建的:

页面视图模型

新的 Sub-ViewModel 实例

ConnectionErrorVM = new ConnectionErrorViewModel();
CurrentView = ConnectionErrorVM;

页面 Xaml

新的子视图实例

<Page.Resources>
   <DataTemplate x:Name="ConnectionErrorViewTemplate" 
               DataType="{x:Type vm:ConnectionErrorViewModel}">
      <v:ConnectionErrorView DataContext="{Binding}" />
   </DataTemplate>
</Page.Resources> ...

//Further down the page in grid
<ContentControl x:Name="ConnectionMessagesView" 
               Content="{Binding CurrentView}"/>

现在第二个在这里创建:

子视图 Xaml

第二个子视图模型

<UserControl.DataContext>
    <vm:SystemErrors/>
</UserControl.DataContext>

现在是第三个:

页面视图模型###

调用 SetActiveError 方法

SystemErrors error = new SystemErrors();
error.SetActiveError(errorCodeToIndex);

看起来这对于 MVVM 中的很多事情来说都是一种有用的方法,但是如果没有额外的实例,我想不出一种方法来做到这一点,因为必须始终在 Sub-View 和 PageView 模型中设置数据上下文总是必须创建一个实例来调用方法。如何在没有像单例这样的创可贴的情况下解决这个问题,或者因为 static 关键字拯救了我们而可以做错事?

标签: c#wpfmvvmdata-binding

解决方案


推荐阅读