MVVM: 根据ViewModel构建窗口

18 浏览
0 Comments

MVVM: 根据ViewModel构建窗口

在我看来,直接从ViewModel打开Views是不好的。理想情况下,ViewModels应该只与其他ViewModels一起工作,而Views应该自动创建。自动创建的意思是ViewModel不知道,更不用说干预了。

我知道这可以通过将控件包含在其他控件中来实现。

可以通过在托管控件的资源中包含DataTemplate来将ViewModel链接到其View:


        
            
        

当ViewModel绑定到托管控件时,它的View就会被渲染出来。

然而,当涉及到创建窗口视图时,我陷入了困境。

如果我像包含控件一样使用相同的方法,就会出现以下异常:

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

这是有道理的。

但是我想不出告诉应用程序生成窗口的其他方法。有吗?

0
0 Comments

在MVVM应用程序中,当涉及到显示顶级窗口时,应该使用一个窗口服务。你可以通过注入一个IWindowService实现来给你的视图模型(view model)注入窗口服务,或者使用一个静态的WindowService类。

代码如下:

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

显然,依赖注入是首选的,因为它可以使你单元测试视图模型类并且在运行时切换IWindowService接口的实现。

我在stackoverflow上看到很多人使用这种方法。尽管如此,我还是坚信视图模型不应该知道视图的实现方式。例如,如果我想要在窗口和其他类型的控件中显示相同的视图模型实例,那该怎么办呢?

请查看我在问题下方的评论来更好地理解我认为有问题的地方。

:我不明白使用服务有什么问题?

直到现在,我一直以为服务的方法是将服务传递给视图模型,然后在视图模型中使用它。我猜这可能是因为这些答案让我这样解释。但正如评论中指出的那样,这并不是真正必要的 - 服务也可以从视图的代码后台调用。所以最后,这可能是正确的。谢谢。

问题的原因是作者认为视图模型不应该知道视图的实现方式,解决方法是使用窗口服务,通过依赖注入的方式将窗口服务注入到视图模型中。作者之前对于窗口服务的理解有误,通过查看其他回答的评论,作者更正了自己的观点。

0