WPF MVVM取消窗口。关闭事件

WPF MVVM取消窗口。关闭事件,wpf,mvvm-light,Wpf,Mvvm Light,在WPF应用程序和MVVMLight工具包中,我想看看您的意见,如果需要取消窗口关闭事件,最好的实现方法是什么。 在Window.Closing事件中,我可以设置e.Cancel=true,这会阻止关闭表单。在ViewModel上下文中,可以确定是否允许关闭或是否应阻止关闭 一种解决方案是,如果我定义了一个应用程序变量,我可以在视图代码隐藏中的普通事件处理程序中查询它 感谢使用MVVM Light,您获得了事件命令: 因此,您可以在xaml中将关闭事件连接到VM <Window ...

在WPF应用程序和MVVMLight工具包中,我想看看您的意见,如果需要取消窗口关闭事件,最好的实现方法是什么。 在Window.Closing事件中,我可以设置e.Cancel=true,这会阻止关闭表单。在ViewModel上下文中,可以确定是否允许关闭或是否应阻止关闭

一种解决方案是,如果我定义了一个应用程序变量,我可以在视图代码隐藏中的普通事件处理程序中查询它


感谢使用MVVM Light,您获得了事件命令

因此,您可以在xaml中将关闭事件连接到VM

<Window ...
        xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
        xmlns:command="http://www.galasoft.ch/mvvmlight">
<i:Interaction.Triggers>
  <i:EventTrigger EventName="Closing">
    <command:EventToCommand Command="{Binding ClosingCommand}"
                            PassEventArgsToCommand="True" />
  </i:EventTrigger>
</i:Interaction.Triggers>
现在在xaml中:

<i:Interaction.Behaviors>
  <local:CancelCloseWindowBehavior CancelClose="{Binding CancelClose}" />
</i:Interaction.Behaviors>


其中,
CancelClose
是来自VM的bool属性,指示是否应取消
关闭
事件。在所附示例中,我有一个
按钮
从虚拟机切换此bool,该按钮应允许您测试
行为
,您可以使用
消息来控制此操作,例如:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        Messenger.Default.Register<CloseApplicationMessage>(this, m => Close());
        Loaded += MainWindowLoaded;
        Closing += MainWindowClosing;
    }

    private void MainWindowClosing(object sender, CancelEventArgs e)
    {
        //Ask for saving
        var closingMessage = new ClosingApplicationMessage();
        Messenger.Default.Send(closingMessage);
        if (closingMessage.Cancel)
            e.Cancel = true;
    }
...
这样,在您正在收听的任何位置,您都可以控制应用程序何时关闭,也可以取消该应用程序。
希望这有助于…

在普通MVVM中,它是带有附加属性的直截了当的。虽然不知道它是如何与MVVMLight一起工作的……是的,这可能是一个解决方案,但我想保留MVVM的优势,尽可能地将视图和模型分开。如何处理这种行为?如果我使用bool值,是否可以取消窗口关闭事件?@pillesoft检查答案末尾的更新,以获取使用
行为执行更新的示例。还有一个下载链接,可以为您提供要测试的项目中的示例。需要记住的一点是,MVVM相对于MVC等模式的主要优势是允许对VM代码进行单元测试。因此,如果您可以在VM fine中对逻辑进行单元测试(在本例中,您可以使用单元测试项目进行单元测试),我个人不会立即将一种方法称为错误的。我可以使用MVVM light方法在事件参数中传递参数吗?行为帮了我的忙,但是如果您有
InvokeCommandAction
和on Closing事件的行为,则首先调用该行为。
<i:Interaction.Behaviors>
  <local:CancelCloseWindowBehavior CancelClose="{Binding CancelClose}" />
</i:Interaction.Behaviors>
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        Messenger.Default.Register<CloseApplicationMessage>(this, m => Close());
        Loaded += MainWindowLoaded;
        Closing += MainWindowClosing;
    }

    private void MainWindowClosing(object sender, CancelEventArgs e)
    {
        //Ask for saving
        var closingMessage = new ClosingApplicationMessage();
        Messenger.Default.Send(closingMessage);
        if (closingMessage.Cancel)
            e.Cancel = true;
    }
...
public class ClosingApplicationMessage
{
    public bool Cancel { get; set; }
}