在 MVVM WPF 中打开新窗口 [英] Opening new window in MVVM WPF

查看:39
本文介绍了在 MVVM WPF 中打开新窗口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个按钮,我将这个按钮绑定到 ViewModel 中的一个命令,比如 OpenWindowCommand.当我点击按钮时,我想打开一个新窗口.但是创建一个窗口实例并从视图模型显示一个窗口是违反 MVVM 的.我已经创建了像

I have a Button and I bind this button to a command in ViewModel say OpenWindowCommand. When I click on the button I want to open a new window. But creating a window instance and showing a window from view model is a violation of MVVM. I have created interface like

interface IWindowService
{
    void showWindow(object dataContext);
}

WindowService 实现这个接口就像

and WindowService implements this interface like

class WindowService : IWindowService
{
    public void showWindow(object dataContext)
    {
        ChildWindow window=new ChildWindow();
        window.DataContext=dataContext;
        window.Show();
    }
}

在这个类中我指定了ChildWindow.所以这个类与显示 ChildWindow 紧密耦合.当我想显示另一个窗口时,我必须实现另一个具有相同接口和逻辑的类.我怎样才能使这个类通用,以便我可以只传递任何窗口的实例,而该类将能够打开任何窗口?

In this class I have specified ChildWindow. So this class is tightly coupled with showing ChildWindow. When I want to show another window, I have to implement another class with the same interface and logic. How can I make this class generic so that I can just pass an instance of any window and the class will be able to open any window?

我没有使用任何内置的 MVVM 框架.我已经阅读了很多关于 StackOverflow 的文章,但我找不到任何解决方案.

I am not using any built MVVM frameworks. I have read many articles on StackOverflow but I could not found any solution for this.

推荐答案

您说创建窗口实例并从视图模型显示窗口违反了 MVVM".这是正确的.

You say "creating window instance and showing window from view model is violation of MVVM". This is correct.

您现在正在尝试创建一个接口,该接口采用 VM 指定的视图类型.这同样是一种违规行为.您可能已经抽象掉了接口背后的创建逻辑,但您仍在请求从 VM 内部创建视图.

You are now trying to create an interface that takes a type of view specified by the VM. This is just as much of a violation. You may have abstracted away the creation logic behind an interface, but you are still requesting view creations from within the VM.

VM 应该只关心创建 VM.如果您确实需要一个新窗口来托管新的 VM,请像您一样提供一个界面,但不要提供一个视图.为什么需要视图?大多数(VM 优先)MVVM 项目使用隐式数据模板将视图与特定 VM 相关联.VM 对它们一无所知.

VM's should only care about creating VM's. If you really need a new window to host the new VM, then provide an interface as you have done, but one that does NOT take a view. Why do you need the view? Most (VM first) MVVM projects use implicit datatemplates to associate a view with a particular VM. The VM knows nothing about them.

像这样:

class WindowService:IWindowService
{
    public void ShowWindow(object viewModel)
    {
        var win = new Window();
        win.Content = viewModel;
        win.Show();
    }
}

显然,您需要确保在 app.xaml 中设置了 VM->View 隐式模板,才能使其正常工作.这只是标准的 VM 优先 MVVM.

Obviously you need to make sure you have your VM->View implicit templates set up in app.xaml for this to work. This is just standard VM first MVVM.

例如:

<Application x:Class="My.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:vm="clr-namespace:My.App.ViewModels"
             xmlns:vw="clr-namespace:My.App.Views"
             StartupUri="MainWindow.xaml">
    <Application.Resources>

        <DataTemplate DataType="{x:Type vm:MyVM}">
            <vw:MyView/>
        </DataTemplate>

    </Application.Resources>
</Application>

这篇关于在 MVVM WPF 中打开新窗口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆