在 WPF 中使用 MVVM,我应该从后面的 View 代码还是 ViewModel 启动子窗口? [英] Using MVVM in WPF, should I launch child windows from View code behind, or ViewModel?

查看:36
本文介绍了在 WPF 中使用 MVVM,我应该从后面的 View 代码还是 ViewModel 启动子窗口?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对此感到困惑有一段时间了.我正在使用 MVVM 模式编写相当大的 RibbonWindow WPF 应用程序.屏幕顶部有一个 RibbonBar 菜单,其余部分显示各种视图.一些视图包含其他视图,其中一些具有启动子 Windows 的按钮.

I've been puzzled by this for a while. I am writing quite a large RibbonWindow WPF application using the MVVM pattern. The screen has a RibbonBar menu along the top and the rest of it displays the various Views. Some Views contain other Views and some of these have buttons that launch child Windows.

到目前为止,我一直在查看代码隐藏文件中执行此操作,但是我知道在使用 MVVM 时这些文件应该是空的.我可以将子窗口启动代码移动到 ViewModel,但随后我需要对主 RibbonWindow 的引用(设置为子窗口所有者),这似乎不对.

So far, I have been doing this from the View code behind file, but I'm aware that these files are supposed to be empty when using MVVM. I could move the child window launch code to the ViewModel, but then I would need a reference to the main RibbonWindow (to set as the child window owner) and that doesn't seem right.

关于如何使用 MVVM 通常实现这一点的任何建议或技巧将不胜感激.

Any advice or tips on how this is normally achieved using MVVM would be greatly appreciated.

推荐答案

我通常通过创建某种 WindowViewLoaderService 来处理这个问题.当您的程序初始化时,您会使用如下代码注册您的 Window 和 ViewModel:

I usually handle this by creating some sort of WindowViewLoaderService. When your program initializes you register your Window's and your ViewModels with code something like this:

WindowViewLoaderService.Register(TypeOf(MainWindowView), TypeOf(MainWindowViewModel));
WindowViewLoaderService.Register(TypeOf(MyWindowView), TypeOf(MyWindowViewModel));

然后,例如,当您可以从您的 ViewModel 调用此服务时,您只需要引用您的另一个 ViewModel.例如,如果您在 MainWindowViewModel 中,您可能有这样的代码:

Then when you can for example call into this service from your ViewModel and all you have to reference is your other ViewModel. For example if you are in your MainWindowViewModel you might have code like this:

var myChildWindowVM = new MyWindowViewModel();
WindowViewLoaderService.ShowWindow(myChildWindowVM);

WindowViewLoaderService 然后会查找与您传递给它的指定 ViewModel 相关联的 View.它将创建该视图,将其 DataContext 设置为您传入的 ViewModel,然后显示该视图.

The WindowViewLoaderService would then look up what View is associated with the specified ViewModel you passed it. It will create that View, Set its DataContext to the ViewModel you passed in, and then display the View.

这样您的 ViewModel 就永远不会知道任何 View.

This way your ViewModels never know about any Views.

您可以轻松推出自己的其中一项服务.它需要做的就是保留一个字典,键是您的 ViewModelType,值是您的 ViewType.Register 方法添加到您的字典中,ShowWindow 方法根据传入的 ViewModel 查找正确的视图,创建视图,设置 DataContext,然后对其调用 Show.

You can roll your own one of these services pretty easily. All it needs to do is keep a Dictionary with the key being your ViewModelType and the value being your ViewType. The Register method adds to your dictionary and the ShowWindow method looks up the correct view based on the ViewModel passed in, creates the view, sets the DataContext, and then calls Show on it.

大多数 MVVM 框架都为您提供了开箱即用的功能.例如,Caliburn 有一个漂亮的,它只使用命名约定,它在这个框架中称为 ViewLocator.这是一个总结的链接:http://devlicio.us/blogs/rob_eisenberg/archive/2010/07/04/mvvm-study-segue-introducing-caliburn-micro.aspx

Most MVVM Frameworks provide something like this for you out of the box. For example Caliburn has a slick one that just uses naming convention its called ViewLocator in this Framework. Here is a link that summarizes: http://devlicio.us/blogs/rob_eisenberg/archive/2010/07/04/mvvm-study-segue-introducing-caliburn-micro.aspx

另一方面,Cinch 将其称为 WPFUIVisualizerService,您可以在此处看到它的实际效果:http://www.codeproject.com/KB/WPF/CinchIII.aspx

Cinch on the other hand calls it a WPFUIVisualizerService which you can see in action here: http://www.codeproject.com/KB/WPF/CinchIII.aspx

这些应该可以帮助您滚动.

These should help get you rolling.

这篇关于在 WPF 中使用 MVVM,我应该从后面的 View 代码还是 ViewModel 启动子窗口?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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