打开MVVM新窗口 [英] Open a new Window in MVVM

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

问题描述

可以说我有一个主窗口和一个MainViewModel,我不是在这个例子中使用MVVM灯和棱镜。
在这个主窗口我想点击一个菜单项或按钮打开一个NewWindow.xaml不是用户控件。
我知道如何使用这个用户控件与在我现有的窗口在ContrntControl打开一个新的用户控件或
一帧。

Lets say I have a MainWindow and a MainViewModel, I'm not using MVVM Light and Prism in this example. In this MainWindow I want to click a MenuItem or Button to open a NewWindow.xaml not a UserControl. I know how to use this with USerControl to open a new UserControl in my existing Window in a ContrntControl or a Frame.

<ContentControl Content="{Binding Path=DisplayUserControl,UpdateSourceTrigger=PropertyChanged}" />

    public ViewModelBase DisplayUserControl
    {
        get 
        {
            if (displayUserControl == null)
            {
                displayUserControl = new ViewModels.UC1iewModel();
            }
            return displayUserControl;
        }
        set 
        {
            if (displayUserControl == value)
            {
                return;
            }
            else
            {
                displayUserControl = value;
                OnPropertyChanged("DisplayUserControl");
            }
        }
    }

在ResourceDitionary的主窗口,我有:

In the ResourceDitionary for MainWIndow i have :

<DataTemplate DataType="{x:Type localViewModels:UC1ViewModel}">
    <localViews:UC1 />
</DataTemplate>
<DataTemplate DataType="{x:Type localViewModels:UC2ViewModel}">
    <localViews:UC2 />
</DataTemplate>

的事情是,我想打开一个新窗口,而不是用户控件。所以我用一些code是这样的:

The thing is that I want to open a new Window, not a User Control. So i use some code like this :

private ICommand openNewWindow;

 public ICommand OpenNewWindow
    {
        get { return openNewWindow; }
    }

  public void DoOpenNewWindow()
    {
        View.NewWindowWindow validationWindow = new View.NewWindow();
        NewWindowViewModel newWindowViewModel = new NewWindowViewModel();
        newWindow.DataContext = ewWindowViewModel;
        newWindow.Show();
    }

,然后绑定OpenNewWindow到一个菜单项或按钮。我知道这是不正确的做法。
但是,这是做到这一点的正确方法?

and then a bind OpenNewWindow to a MenuItem or Button. I know this is not the right way. But which is the right way to do this ?

谢谢!

推荐答案

有你需要这种类型的应用解决两个问题。

There are two problems you need to solve with this type of application.

首先,你不希望有视图模型创建和直接显示的UI组件。其中一个动机使用MVVM的是到您的视图模型引入测试能力,并具有此类弹出新视窗,使该类更难的测试。

Firstly, you do not want to have the View-Model creating and displaying UI components directly. One of the motivations for using MVVM is to introduce test-ability in to your View-Model, and having this class pop up new windows makes this class harder to test.

您需要解决的第二个问题是如何解决的依赖关系在你的应用程序,或者在这种情况下 - 怎么给你挂钩的视图模型到相应的视图?到后一问题的维护的解决方案是通过使用DI容器的给出。一个很好的参考这个问题是由.NET 马克·塞曼的依赖注入给出。他居然还讨论了如何解决第一个问题呢!

The second problem you need to solve is how to resolve the dependencies in your application, or in this instance – how to you "hook up" the View-Model to the corresponding View? A maintainable solution to this latter problem is given by the use of a DI container. A very good reference to this subject is given by Mark Seemann’s Dependency Injection in .NET. He actually also discusses how to solve the first problem too!

要解决前一个问题,你需要引入一个间接层到code,使视图模型不依赖于具体实现创建一个新的窗口。

To solve the former problem, you need to introduce a layer of indirection to your code, to make the View-Model not dependent on a concrete implementation of creating a new window. A very simple example is given in the code below:

public class ViewModel
{
    private readonly IWindowFactory m_windowFactory;
    private ICommand m_openNewWindow;

    public ViewModel(IWindowFactory windowFactory)
    {
        m_windowFactory = windowFactory;

        /**
         * Would need to assign value to m_openNewWindow here, and associate the DoOpenWindow method
         * to the execution of the command.
         * */
        m_openNewWindow = null;  
    }

    public void DoOpenNewWindow()
    {
        m_windowFactory.CreateNewWindow();
    }

    public ICommand OpenNewWindow { get { return m_openNewWindow; } }
}

public interface IWindowFactory
{
    void CreateNewWindow();
}

public class ProductionWindowFactory: IWindowFactory
{

    #region Implementation of INewWindowFactory

    public void CreateNewWindow()
    {
       NewWindow window = new NewWindow
           {
               DataContext = new NewWindowViewModel()
           };
       window.Show();
    }

    #endregion
}

请注意您采取 IWindowFactory 的实施在您的​​视图模型的构造,它是这个对象的新窗口的创建委托给。这使您可以替代生产实施测试过程中不同的功能。

Note that you take an implementation of IWindowFactory in the constructor of your View-Model, and it is to this object that the creation of the new window is delegated to. This allows you to substitute the production implementation for a different one during testing.

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

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