WPF MVVM 取消 Window.Closing 事件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23613694/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 11:42:35  来源:igfitidea点击:

WPF MVVM cancel Window.Closing event

wpfmvvm-light

提问by pillesoft

In WPF application together with MVVMLight Toolkit, I would like to see your opinion, what is the best way to implement if I need to Cancel the Window Close event. In Window.Closing event I can set the e.Cancel = true, which prevents closing the form. To identify if the Close is allowed, or should be prevented is in the ViewModel context.

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

One solution could be if I define an Application variable, and I can query this in the normal event handler in view code behind?

一种解决方案可能是,如果我定义一个 Application 变量,并且我可以在后面的视图代码中的普通事件处理程序中查询它?

thanks

谢谢

回答by Viv

With MVVM Light you got EventToCommand:

使用 MVVM Light,您将获得EventToCommand

So you could in xaml wire up the closing event to the VM.

因此,您可以在 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>

and in the VM:

在虚拟机中:

public RelayCommand<CancelEventArgs> ClosingCommand { get; private set; }

ctor() {
  ClosingCommand = new RelayCommand<CancelEventArgs>(args => args.Cancel = true);
}

If you do not want to pass CancelEventArgsto the VM:

如果您不想传递CancelEventArgs给 VM

You could always take the similar approach with a Behaviorand just use a simple boolfrom the VM(bind this bool to the Behavior) to indicate the closing event should be cancelled.

您始终可以采用类似的方法 aBehavior并仅使用boolVM 中的简单(将此 bool 绑定到行为)来指示应取消关闭事件。

Update:

更新:

Download Link for following example

以下示例的下载链接

To do this with a Behavioryou could just have a Behaviorsuch as:

要使用 a 执行此操作,Behavior您可以只需要一个Behavior例如:

internal class CancelCloseWindowBehavior : Behavior<Window> {
  public static readonly DependencyProperty CancelCloseProperty =
    DependencyProperty.Register("CancelClose", typeof(bool),
      typeof(CancelCloseWindowBehavior), new FrameworkPropertyMetadata(false));

  public bool CancelClose {
    get { return (bool) GetValue(CancelCloseProperty); }
    set { SetValue(CancelCloseProperty, value); }
  }

  protected override void OnAttached() {
    AssociatedObject.Closing += (sender, args) => args.Cancel = CancelClose;
  }
}

Now in xaml:

现在在 xaml 中:

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

Where CancelCloseis a bool property from the VM which indicates if the Closingevent should be cancelled or not. In the attached example I have a Buttonto toggle this bool from the VM that should let you test the Behavior

哪里CancelClose是 VM 的 bool 属性,指示是否Closing应取消事件。在附加的示例中,我有一个Button从 VM 切换此布尔值的方法,它应该让您测试Behavior

回答by Raúl Ota?o

You could to control this using Messages, for instance:

您可以使用 来控制它Messages,例如:

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;
    }
...

The mvvm message:

mvvm 消息:

public class ClosingApplicationMessage
{
    public bool Cancel { get; set; }
}

In this way, in any place you are listening to the ClosingApplicationMessage, you can control when the application is going to close, and may to cancel it. Hope this helps...

这样,在您收听 的任何地方ClosingApplicationMessage,您都可以控制应用程序何时关闭,也可以取消。希望这可以帮助...