在ViewModel应该如何关闭该窗体? [英] How should the ViewModel close the form?
问题描述
我想学习WPF和MVVM问题,但遇到了阻碍。
这个问题是相似但不完全相同这一个(处理,对话功能于WPF -with-MVVM) ...
I'm trying to learn WPF and the MVVM problem, but have hit a snag. This question is similar but not quite the same as this one (handling-dialogs-in-wpf-with-mvvm)...
我有一个登录的形式书面使用MVVM模式。
I have a "Login" form written using the MVVM pattern.
这形式有一个ViewModel持有的用户名和密码,这必将对使用正常的数据绑定在XAML视图。
它也有一个登录,这是绑定到登录按钮的形式,阿甘使用正常的数据绑定的命令。
This form has a ViewModel which holds the Username and Password, which are bound to the view in the XAML using normal data bindings. It also has a "Login" command which is bound to the "Login" button on the form, agan using normal databinding.
在登录命令火灾,它调用其中熄灭,并通过网络将数据发送到登录视图模型的函数当此功能完成后,有2个动作:
When the "Login" command fires, it invokes a function in the ViewModel which goes off and sends data over the network to log in. When this function completes, there are 2 actions:
-
登录无效 - 我们只是显示一个MessageBox所有的罚款
The login was invalid - we just show a MessageBox and all is fine
登录是有效的,我们需要关闭登录窗体,并将它作为返回true的的DialogResult
...
The login was valid, we need to close the Login form and have it return true as its DialogResult
...
问题是,视图模型一无所知实际的看法,所以它怎么能关闭视图并告诉它返回一个特定的DialogResult?我能沾些code在codeBehind,和/或通过向视图模型通过查看,但看起来它会破坏MVVM整点完全...
The problem is, the ViewModel knows nothing about the actual view, so how can it close the view and tell it to return a particular DialogResult?? I could stick some code in the CodeBehind, and/or pass the View through to the ViewModel, but that seems like it would defeat the whole point of MVVM entirely...
在最后我只是违反了MVVM模式的纯洁,不得不查看发布关闭
事件,暴露出一个关闭
方法。然后,视图模型只是调用 view.Close
。该视图只通过一个接口知并通过IOC容器接线,所以没有可测试性和可维护性会丢失。
In the end I just violated the "purity" of the MVVM pattern and had the View publish a Closed
event, and expose a Close
method. The ViewModel would then just call view.Close
. The view is only known via an interface and wired up via an IOC container, so no testability or maintainability is lost.
这似乎相当愚蠢的接受的答案是在-5票!虽然我很清楚那一个得到通过而被纯解决问题的好感情,当然我不是认为200行的事件,命令和行为,只是为了避免单行法的唯一的模式和纯洁的名字有点可笑......
It seems rather silly that the accepted answer is at -5 votes! While I'm well aware of the good feelings that one gets by solving a problem while being "pure", Surely I'm not the only one that thinks that 200 lines of events, commands and behaviors just to avoid a one line method in the name of "patterns" and "purity" is a bit ridiculous....
推荐答案
我的灵感来自于<一个href=\"http://stackoverflow.com/questions/501886/wpf-mvvm-newbie-how-should-the-viewmodel-close-the-form/1153602#1153602\">Thejuan's回答写一个简单的附加属性。没有风格,没有触发;相反,你可以这样做:
I was inspired by Thejuan's answer to write a simpler attached property. No styles, no triggers; instead, you can just do this:
<Window ...
xmlns:xc="clr-namespace:ExCastle.Wpf"
xc:DialogCloser.DialogResult="{Binding DialogResult}">
这几乎是那样干净,如果WPF队右侧得到它,并在第一时间做出的DialogResult一个依赖属性。只要把一个布尔?在你的视图模型的DialogResult
属性和实现INotifyPropertyChanged,并瞧,您的视图模型可以只通过设置属性关闭窗口(并设置其的DialogResult)。 MVVM理所应当的。
This is almost as clean as if the WPF team had gotten it right and made DialogResult a dependency property in the first place. Just put a bool? DialogResult
property on your ViewModel and implement INotifyPropertyChanged, and voilà, your ViewModel can close the Window (and set its DialogResult) just by setting a property. MVVM as it should be.
这里的code为DialogCloser:
Here's the code for DialogCloser:
using System.Windows;
namespace ExCastle.Wpf
{
public static class DialogCloser
{
public static readonly DependencyProperty DialogResultProperty =
DependencyProperty.RegisterAttached(
"DialogResult",
typeof(bool?),
typeof(DialogCloser),
new PropertyMetadata(DialogResultChanged));
private static void DialogResultChanged(
DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
var window = d as Window;
if (window != null)
window.DialogResult = e.NewValue as bool?;
}
public static void SetDialogResult(Window target, bool? value)
{
target.SetValue(DialogResultProperty, value);
}
}
}
我也张贴了这个上我的博客。
这篇关于在ViewModel应该如何关闭该窗体?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!