简体   繁体   English

MVVM Light-多个ViewModel(并将它们连接起来)

[英]MVVM Light - Multiple ViewModels (and connecting them up)

I am trying to learn the MVVM pattern (C#), having come from a Windows Forms background. 我正在尝试从Windows Forms背景中学习MVVM模式(C#)。 I am using the MVVM Light toolkit, and so far I think it is brilliant. 我正在使用MVVM Light工具包,到目前为止,我认为它很棒。 I have made several small applications, however one thing I am struggling with is introducing a second view. 我做了几个小型应用程序,但是我正在努力的一件事就是引入第二种观点。

I want to (for example), have a button on my MainViewModel, which via a RelayCommand, opens up a new Window - let's say an "About" window. 我想(例如)在MainViewModel上有一个按钮,该按钮通过RelayCommand打开一个新窗口-假设是一个“关于”窗口。 I have done hours of research on the web for this however it seems I can't get my AboutViewModel to communicate with/show my AboutView. 我已经在网上进行了数小时的研究,但是看来我无法让AboutViewModel与我的AboutView进行交流/显示。

I have placed a receiving messenger in the code-behind constructor of the AboutView.xaml - however I can't get it to receive any messages from the AboutViewModel, and thus can't make it 'Show()'. 我已经在AboutView.xaml的代码隐藏构造函数中放置了一个接收消息传递器-但是,我无法使它接收来自AboutViewModel的任何消息,因此无法使其成为“ Show()”。

If anyone has an example of an Mvvm Light WPF app using multiple views that would be great :) 如果有人举了一个使用多个视图的Mvvm Light WPF应用示例,那将是很好的:)

There are two ways I can think to do this easily 我可以通过两种方法轻松地做到这一点

The first would be to use a Popup instead of a new Window . 第一种是使用Popup而不是新Window For example, I often put properties in my ViewModel for PopupContent and IsPopupVisible , and set those values anytime I want to display my Popup control. 例如,我经常在ViewModelPopupContentIsPopupVisible放置属性,并在我想显示Popup控件的任何时候设置这些值。 For example, a ShowAboutPopup relay command might run something like this: 例如, ShowAboutPopup中继命令可能会运行以下命令:

void ShowAboutPopup()
{
    PopupContent = new AboutViewModel();
    IsPopupVisible = true;
}

You can display it using a Popup object, or a custom UserControl . 您可以使用Popup对象或自定义UserControl显示它。 I prefer to use my own custom Popup UserControl , which will usually end up looking like this: 我更喜欢使用自己的自定义Popup UserControl ,通常将最终看起来像这样:

<Window>
    <Canvas x:Name="RootPanel">
        <SomePanel>
            <!-- Regular content goes here -->
        </SomePanel>

        <local:PopupPanel Content="{Binding PopupContent}"
            local:PopupPanel.IsPopupVisible="{Binding IsPopupVisible}"
            local:PopupPanel.PopupParent="{Binding ElementName=RootPanel}" />
    </Canvas>
</Window>

The PopupContent property is a ViewModel (such as an AboutViewModel ), and DataTemplates are used to tell WPF to draw specific ViewModels with specific Views PopupContent属性是一个ViewModel (例如AboutViewModel ),并且DataTemplates用于告诉WPF使用特定的Views绘制特定的ViewModels

<Window.Resources>
    <DataTemplate DataType="{x:Type local:AboutViewModel}">
        <local:AboutView />
    </DataTemplate>
</Window.Resources>

The other method is to have some kind of ApplicationViewModel that runs on startup, and is responsible for the overall application state, which includes which window(s) are open. 另一种方法是让某种ApplicationViewModel在启动时运行,并负责整个应用程序状态,其中包括打开了哪些窗口。

Typically I prefer to have a single ApplicationView that contains a ContentControl to display the current page 通常,我更喜欢使用一个包含ContentControl ApplicationView来显示当前页面

<Window>
    <ContentControl Content="{Binding CurrentViewModel}" />
</Window>

however it can also be used to manage multiple windows. 但是,它也可以用于管理多个窗口。 If you do use it to manage multiple Window objects, be warned that this will not be a pure ViewModel because it will need to access some View-specific objects, and referencing UI objects it not something a ViewModel should do. 如果确实使用它来管理多个Window对象,请注意,这将不是纯ViewModel因为它将需要访问某些特定于View的对象,并且引用UI对象不是ViewModel应该做的。 For example, it may subscribe to receive ShowWindow messages, and upon receiving those messages it would create the specified View and show it, and possibly hide the current window as well. 例如,它可以订阅接收ShowWindow消息,并且在接收到这些消息后,它将创建指定的View并将其显示,并且还可能隐藏当前窗口。

Personally, I try to avoid multiple windows as much as possible. 我个人尽量避免使用多个窗口。 My usual method is to have a single View that contains consistent application objects for any page, and a ContentControl containing dynamic content that changes. 我通常的方法是拥有一个包含任何页面的一致应用程序对象的View,以及一个包含变化的动态内容的ContentControl I have an example using this navigation style on my blog if you're interested 如果您感兴趣,我在我的博客上有一个使用此导航样式示例

As i can see you want a navigation in your MVVM app? 如我所见,您想在MVVM应用程序中导航?

Word goes to the creator of MVVM Light - Laurent Bugnion - with his post about using Navigation Service for switching Views . 字去的创造者MVVM Light - 洛朗比尼翁 -与他的职位有关使用导航服务切换Views It's actually about Windows Phone & Silverlight but same should apply to WPF . 它实际上是关于Windows PhoneSilverlight的,但同样适用于WPF

Also this answer in related question uses this approach. 相关问题中的这个答案也使用这种方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM