WPF(MVVM):closuresViewmodel的视图?

任何人碰到使用MVVM在视图模型中closures视图的巧妙方法?

也许有一种使用绑定的方式来指示视图(窗口)closures?

我真的很感激任何人有任何input。

基本上我有一个loginView绑定到一个loginViewModel,在viewmodel(使用一个命令绑定)我testing,看看如果login是成功的,如果是我基本上加载一个新的视图(主视图),并附加其datacontext。 ..

但我仍然有loginView显示 – 所以我需要信号它卸载..

我也希望有一个通用的解决scheme,因为我相信在其他情况下我需要做这种事情

有任何想法吗?

编辑:看我的博客文章更详细的解释。

当我需要实现这一点时,我使用我创build的IRequestCloseViewModel接口。

该接口只包含一个事件:RequestClose。 这个事件是由ViewModel(它inheritance自一个ViewModelBase类和实现IRequestCloseViewModel)当它想要closures它的相关视图引发的。

在我的应用程序中,所有Window都从一个抽象类ApplicationWindowinheritance。 每当DataContext发生变化时,都会通知此抽象类,并在处理程序中检查DataContext是否支持IRequestCloseViewModel。 如果是这种情况,事件处理程序被设置为当事件被触发时closures窗口。

或者像肯特所说的那样,你可以使用屏幕控制器来处理这个外部类的机制。

不知道你正在使用什么MVVM框架,但大多数包含某种消息/通知解决scheme,很容易注册发送的消息的东西。 没有任何理由可以想象你的视图不能注册诸如“CloseWindowsBoundTo”之类的消息,并且视图模型作为发送者。 然后在你的视图中,你可以注册该消息,并将你当前的datacontext与发送者进行比较。 如果他们匹配,closures窗口。

简单,并保持你的视图从你的视图模型抽象。

这里是我使用MVVM-light工具包的方法:

在ViewModel中:

public void notifyWindowToClose() { Messenger.Default.Send<NotificationMessage>( new NotificationMessage(this, "CloseWindowsBoundToMe") ); } 

而在视图中:

 Messenger.Default.Register<NotificationMessage>(this, (nm) => { if (nm.Notification == "CloseWindowsBoundToMe") { if (nm.Sender == this.DataContext) this.Close(); } }); 

一般情况下,您可以使用某种控制器/演示者/服务来驱动屏幕激活/停用。 MVVM并不意味着成为统治它们一种模式 。 您将需要在任何非平凡的应用程序中将其与其他模式相结合。

也就是说,在某些情况下,有一个pipe理子视图模型生命周期的视图模型是有意义的。 例如,您可能有一个EditorViewModel来pipe理子视图模型的集合 – 每个正在编辑的文档都有一个。 在这种情况下,简单地添加/删除/从这个集合可以导致视图激活/停用。 但是这听起来不像你的用例。

http://adammills.wordpress.com/2009/07/01/window-close-from-xaml/

<Style.Triggers> <DataTrigger Binding="{Binding CloseSignal}" Value="true"> <Setter Property="Behaviours:WindowCloseBehaviour.Close" Value="true" /> </DataTrigger> </Style>

我知道这是一个古老的问题,但我有一个很好的方式,所以我想我会分享给其他人绊倒这一点。 我曾经使用dialogcloser附加的行为,但我发现下面的解决scheme,我可以使用它更容易。 为简单起见,下面的示例为窗口上的closuresbutton示例。

通过窗口作为命令参数。

在buttonxaml中查看:

 CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}" 

在视图模型中的命令execute方法中:

 if (parameter is System.Windows.Window) { (parameter as System.Windows.Window).Close(); } 

您可以创build一个附加到窗口的命令,并在执行时closures该窗口。 然后,可以将该命令绑定到视图模型上的属性,并在要closures窗口时执行该命令。

我会使用一个ApplicationController实例化LoginViewModel并显示LoginView。 当用户进入login屏幕时,ApplicationControllerclosuresLoginView并显示MainViewModel的MainView。

WPF应用程序框架(WAF)项目的示例应用程序中显示了如何完成此任务。

这个答案显示了另一种方式来做到这一点

ViewModel应该如何closures表单?

它使用附加属性将DialogResult窗口属性绑定到ViewModel属性。 当将DialogResult的值设置为true或false时,视图被closures。

只需在后台代码中的EventHandler中closures,并在视图模型中处理其他任何可以使用命令绑定的地方。

要closuresviewmodel的视图,我使用了Galasoft MVVM Light Toolkit,你可以从这里下载: http ://www.mvvmlight.net/

  1. 像这样创build一个类:public class ClosingRequested:MessageBase {}

  2. 把这个添加到你的视图构造函数:Messenger.Default.Register(this,vm,msg => Close());

  3. 调用这个来closures你的窗口:Messenger.Default.Send(new ClosingRequested(),this);

你也可以使用事件来做到这一点。 虽然你需要在你的视图代码背后需要3行代码(有些MVVM纯粹主义者不喜欢这样);

在你的viewmodel中,你创build了一个视图可以订阅的事件:

  public event CloseEventHandler Closing; public delegate void CloseEventHandler(); private void RaiseClose() { if (Closing != null) Closing(); } 

在你的视图中,你可以在你的initializecomponent方法之后订阅这个事件,如下所示:

  public View { *//The event can be put in an interface to avoid direct dependence of the view on the viewmodel. So below becomes //ICloseView model = (ICloseView)this.DataContext;* ProgressWindowViewModel model = (ProgressWindowViewModel)this.DataContext; model.Closing += Model_Closing; } private void Model_Closing() { this.Close(); } 

当您准备好closuresViewModel中的视图时,只需调用RaiseClose()即可。

您甚至可以使用此方法将消息从视图模型发送到视图。

事件可以放在一个接口中,以避免视图对视图模型的直接依赖。