WPF MVVM 对话框示例
有谁有使用 MVVM (Prism) 显示窗口对话框的示例吗? - 例如,执行命令时的配置设置窗口。
我见过的所有示例都使用中介模式,这很好,但它们也都引用了视图模型中的视图,这并不理想(我们正在使用 DataTemplates)
谢谢
Does anyone have any examples of showing a window dialog using MVVM (Prism)? - for example a configuration settings window when a command is executed.
All of the examples I've seen use the mediator pattern which is fine, but they also all have a reference to the view in the view model which is not ideal (we're using DataTemplates)
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我将使用一项服务来显示对话框。然后,该服务还可以将视图与视图模型链接起来。
RegisterView
只是将视图类型与 ViewModel 类型链接起来。您可以在模块初始化中设置这些链接。这比尝试让模块在应用程序顶层注册数据模板更简单。ShowDialog
显示您想要显示的 ViewModel。它返回 true、false 和 null 来关闭,就像 Window.ShowDialog 方法一样。该实现只是从容器中创建一个TView
类型的新视图,将其连接到提供的 ViewModel 并显示它。IDialogViewModel
为ViewModel提供了一种机制来进行验证并取消对话框的关闭。我有一个标准对话框窗口,其中有一个内容控件。当调用 ShowDialog 时,它会创建一个新的标准对话框,将视图添加到内容控件,连接 ViewModel 并显示它。标准对话框已经具有[确定]和[取消]按钮,具有适当的逻辑来从
IDialogViewModel
调用正确的方法。I would use a service to display the dialog. The service can then also link views with viewmodels.
RegisterView
just links the view type with the ViewModel type. You can set up these links in the module initialization. This is simpler than trying to get modules to register datatemplates in the top layer of your application.ShowDialog
Shows the ViewModel you want to display. It returns true, false and null for close just like theWindow.ShowDialog
method. The implementation just creates a new view of typeTView
from your container, hooks it up to the provided ViewModel, and shows it.IDialogViewModel
provides a mechanism for the ViewModel to do verification and cancel the closing of the dialog.I have a standard dialog window, with a content control in it. When
ShowDialog
is called it creates a new standard dialog, adds the view to the content control, hooks up the ViewModel and displays it. The standard dialog already has [OK] and [Cancel] buttons with the appropriate logic to call the right methods fromIDialogViewModel
.我这样做的方法也是使用中介者模式。当 ViewModel 想要显示对话框时,它会发送一条消息,该消息由应用程序的主窗口接收。该消息包含对话框使用的 ViewModel 实例。
然后主窗口构造一个对话框窗口的实例,将视图模型传递给它并显示对话框。对话的结果通过原始消息传递回调用者。
它看起来像这样:
在你的视图模型中:
在主窗口代码隐藏中:
我希望这足以给你这个想法......
The way I do this is using the mediator pattern also. When the ViewModel wants to show a dialog, it sends a message which is picked up by the application's main window. The message contains an instance of the ViewModel used by the dialog.
The main window then constructs an instance of the dialog window, passes the view model to it and shows the dialog. The result of the dialog is passed back to the caller in the original message.
It looks something like this:
In your view model:
In the main window codebehind:
I hope this is enough to give you the idea...
我同意,使用服务根据 MVVM 模式显示对话框是最简单的解决方案。但是,我也问自己,如果我的项目中有 3 个程序集 Model、ViewModel、View,并且根据 MVVM 模式程序集 ViewModel 引用了 Model,而 View 引用了 Model 和 ViewModel,我应该在哪里放置 DialogService 类?如果我在 ViewModel 程序集中放置一个 - 我就没有机会创建 DialogView 实例;另一方面,如果我将 DialogService 放在 View 程序集中,我应该如何将它注入到我的 ViewModel 类中?
因此,我建议查看使用 Prism 的高级 MVVM 场景 部分:使用交互请求对象
作为此方法的示例:
DialogViewModelBase
CreateUserStoryViewModel:
CreateUserStoryRequest
CreateUserStory Command
XAML:
I'm agreed, that using service to display dialog according to MVVM pattern is the most simple solution. But, I also asked myself, if there are 3 assemblies in my project Model, ViewModel, View and according to MVVM pattern assembly ViewModel has a reference to Model, and View to both Model and ViewModel where should I place DialogService class? If I will place one in the ViewModel assembly - I have no chances to create DialogView instance; on the other hand, if I will place DialogService in the View assembly, how I should inject it in my ViewModel class?
So, I would recoment look at Advanced MVVM scenarios with Prism Part: Using Interaction Request Objects
As example of this approach:
DialogViewModelBase
CreateUserStoryViewModel:
CreateUserStoryRequest
CreateUserStory Command
XAML:
正如我理解您上面的评论一样,问题不在于显示对话框,而在于隐藏它们。有两种方法可以解决这个问题:
使用标准对话框窗口来实现视图。这需要 View 和 ViewModel 之间采用松散耦合的通信方式,以便 ViewModel 可以通知 View 可以在不引用视图的情况下关闭。
有多个框架可以实现这一点 - Prism 的事件聚合器就是其中之一。在这种情况下,View 将订阅一个事件(例如 MyDialogResultValidated),并在接收到该事件时相应地设置 DialogResult。如果验证成功,ViewModel(在其 SaveCommand 中)将触发该事件。
不要使用标准对话框窗口来实现视图。这需要有一个能够有效模拟模态的覆盖层。
在这种情况下,视图和覆盖层的可见性将绑定 ViewModel 的 IsVisible 属性,该属性将通过 SaveCommand 实现进行相应设置,或者每当 ViewModel 需要显示视图时进行相应设置。
第一种方法需要在代码隐藏中添加一些代码,需要添加全局事件,并且(可以说)不太像 MVVM 风格。第二种方法需要实现(或使用其他人的实现)覆盖,但不需要在代码隐藏中包含任何代码,不需要具有全局事件,并且(有争议)更接近 MVVM 。
As I understood your comment above, the question is not so much about showing the dialogs as about hiding them. There are two ways to solve this problem:
Use standard dialog window to implement the view. This would require to have a loosely coupled way of communication between View and ViewModel so that ViewModel can notify the View that it's ok to close without having a reference to a view.
There are multiple frameworks exist that would allow to do it - Prism's event aggregators would be one of them. In this scenario View would subscribe to an event (say, MyDialogResultValidated), and on receiving the event it would set the DialogResult accrodingly. ViewModel (in its SaveCommand) would fire the event if validation was successful.
Don't use standard dialog window to implement the view. This would require to have an overlay that would effectively emulate modality.
In this scenario the Visibility of the View and of the overlay will be bound ViewModel's IsVisible property that would be set accordingly by SaveCommand implementation, or whenever ViewModel needs to show the View.
The first approach would require having a bit of code in code-behind, requires adding global event(s), and (arguably) is less MVVM-ish. The second approach would require implementing (or using someone else's implementation) of the overlay, but won't require having any code in code-behind, won't require having global event(s), and is (arguable) more MVVM-ish.
您可能对以下示例应用程序感兴趣:
http://compositeextensions.codeplex.com
它使用带有PresentationModel(又名MVVM)模式的Prism2。示例应用程序包含一个模式对话框。
You might be interested in the following sample application:
http://compositeextensions.codeplex.com
It uses Prism2 with the PresentationModel (aka MVVM) pattern. The sample application contains a modal dialog.
它不是 Prism,但这个 MVVM 演示 具有一个完全完整的选项对话框MVVM。
It isn't Prism, but this MVVM demo has an Options Dialog that's fully MVVM.