【问题标题】:MVVM: Construct window based on ViewModel [duplicate]MVVM:基于 ViewModel 构建窗口 [重复]
【发布时间】:2020-06-17 00:27:03
【问题描述】:

在我看来,直接从 ViewModel 中打开 View 是一件坏事。理想情况下,ViewModel 应该只与其他 ViewModel 一起使用,并且应该自动创建 View。我所说的自动是指在 ViewModel 不知道的情况下,更不用说干预了。

我知道这可以通过其他控件中包含的控件来实现。 ViewModel 可以通过在宿主控件的资源中包含一个 DataTemplate 来链接到它的 View:

<UserControl.Resources>
        <DataTemplate DataType="{x:Type vm:BasicSetupViewModel}">
            <vw:BasicSetupPane/>
        </DataTemplate>
</UserControl.Resources>

当 ViewModel 被绑定到宿主控件时,它的 View 就会被渲染。

但是,我在创建窗口视图时遇到了困难。 如果我使用与包含控件相同的方法,我会得到这个异常:

System.Windows.Markup.XamlParseException: 'Window must be the root of the tree. Cannot add Window as a child of Visual.'

这是有道理的。 然而,我想不出任何其他方式来告诉应用程序应该生成窗口。有吗?

【问题讨论】:

  • 您可以在 OpenFileDialog A: Open File Dialog MVVM 的示例中了解如何在 MVVM 中使用对话框。
  • @ASh 感谢您的提示。我以前看过一些这样的帖子,但我不能说我对这种方法很满意。我希望有一个 ViewModel 真正独立于 View 实现的解决方案。
  • @Rekshino 我也有类似的问题。但是,我觉得有趣的是链接问题的different answer。我会进一步检查它。谢谢。
  • 这是很多问题,这通常表明潜在问题过于宽泛,不适合 Stack Overflow。您的问题有很多个可能的、有效的答案。也就是说,为了解决您的问题的更广泛意义:一个选项是,例如,您的服务中的“当前”方法。您将视图模型传递给它,它知道如何处理它(即找到正确的窗口类型创建一个实例并显示窗口)。它应该被称为“在适当的时候”,这可能会根据您的实际业务逻辑而有很大差异。 ...
  • ... 这些都不排除在其他上下文中使用完全相同的视图模型。您可以根据需要在现有视图(窗口、用户控件等)中应用模板。我不鼓励有多个窗口类型呈现相同的视图模型对象,但你甚至可以这样做;你只需要决定你将使用什么机制让服务知道如何区分这些场景。

标签: wpf xaml mvvm


【解决方案1】:

在 MVVM 应用程序中显示顶级窗口时,您应该使用window service。

您可以使用IWindowService 实现注入您的视图模型,也可以使用静态WindowService 类:

public static class WindowService
{
    public static void OpenWindow()
    {
        NewView view = new NewView();
        view.Show();
    }
}

依赖注入显然更可取,因为它使您能够对视图模型类进行独立的单元测试,并在运行时切换IWindowService 接口的实现。

【讨论】:

  • 我在 SO 上看到很多人使用这种方法。尽管如此,我还是忍不住认为 ViewModel 不应该知道 View 是如何实现的。例如,如果我想在窗口和另一种控件中显示相同的 ViewModel 实例怎么办?
  • 请在问题下方查看我的 cmets,以更好地了解我发现的问题。
  • @zvizesna:我不明白使用服务有什么“问题”?
  • 到目前为止,我已经理解了服务方法,即您将服务传递给 ViewModel 并从那里使用它。我猜thiskindof answers 让我这样解释它。但正如@PeterDuniho 在 cmets 中指出的那样,这并不是真正必要的——该服务也可以从 View 的代码隐藏中调用。所以毕竟,这可能是正确的。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-13
  • 2011-05-27
  • 2016-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-09
相关资源
最近更新 更多