从 ViewModel 打开一个窗口 [英] Open a window from ViewModel

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

问题描述

我正在尝试使我的 WPF 应用程序解耦,因此我做了类似的事情:

I am trying to make my WPF application decoupled and thus I did something like:

  • 视图的项目.

  • Project of the View.

ViewModel 的项目.

Project of the ViewModel.

mainwindow 中,我将按钮绑定到位于 ViewModel DLL 中的 OpenChildWindowCommand.

In the mainwindow I did binding between a button to an OpenChildWindowCommand which is located in the ViewModel DLL.

OpenChildWindowCommand 继承自 ICommand 并执行对 MainViewModel 中的 OpenChildWindow 方法的调用.

OpenChildWindowCommand inherits from ICommand and execute a call to OpenChildWindow method in the MainViewModel.

现在的问题是 ViewModel 不知道 ChildWindow,因为它是一个不同的 DLL.

Now the problem is that the ViewModel does not know about the ChildWindow because it is a different DLL.

我要问的是:最好的方法是什么 - 将打开子窗口?

What I'm asking is: what is the best way doing it - that the child window will be opened?

也许是他们之间的某种信息传递.

Maybe some kind of messaging between them.

推荐答案

首先,我祝贺您将视图与视图模型物理分离 - 将它们放在同一个程序集中会导致许多人采取他们不应该走的捷径.

First of all I congratulate you on physically separating your views from your viewmodels - keeping them in the same assembly leads many people into taking shortcuts that they shouldn't.

使用您的按钮绑定,我建议您将命令代码放在视图后面的代码中.正是与视图的交互导致子窗口被打开,因此从根本上说命令代码不需要在视图模型中.您的代码将如下所示:

With your button binding I would suggest that you put the command code in the code behind of the view. It is an interaction with the view that is causing the childwindow to be opened, so there is fundamentally no reason why the command code needs to be in the viewmodel. Your code will look something like this:

public ICommand OpenChildWindowCommand
{
    get 
    {
        return new DelegateCommand<object>(ExecuteOpenChildWindowCommand, CanOpenChildWindowCommandExecute);
    }
}

private void ExecuteOpenChildWindowCommand(object context)
{
    ...code to open the child window...
}

private void CanOpenChildWindowCommandExecute(object context)
{
    return true;
}

(DelegateCommand 来自微软的 PRISM 库).您的 XAML 将如下所示:

(The DelegateCommand<T> is from Microsoft's PRISM library). Your XAML will look something like this:

<Button x:Name="MyButtonName" 
        Command="{Binding OpenChildWindowCommand, RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}" 
        />

然后我建议您开始使用对话服务 - 这是一些与对话相关的代码,被抽象为独立的帮助程序样式服务.进入对话服务的细节会使这个答案有点长,所以这里有一些有用的链接可以帮助您入门:

What I suggest you do then is start using a dialog service - this is some dialog related code that is abstracted into a standalone helper style service. Going into the details of a dialog service will make this answer a bit long, so here's some helpful links to get you started:

如果您将新的对话服务与使用 IoC 容器相结合,那么您可以拥有一些非常好的解耦 MVVM 并测试如下所示的友好代码:

If you combine your new dialog service with using an IoC container then you can have some very nice decoupled MVVM and test friendly code that looks like this:

public class MyMainWindow
{
    private IDialogService dialogService;

    public MyMainWindow(IUnityContainer container)
    {
        dialogService = container.Resolve<IDialogService>();
    }

    private void ExecuteOpenChildWindowCommand(object context)
    {
        var dlg = _dialogService.Show<IMyDialogWindow>();
    }
}

(您在应用程序启动的早期初始化容器并将接口注册到具体的类映射).

(You initialise the container and register the interface to concrete class mappings early on in application startup).

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

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