如何在 MVVM WPF 应用程序中取消窗口关闭 [英] How to cancel window closing in MVVM WPF application

查看:79
本文介绍了如何在 MVVM WPF 应用程序中取消窗口关闭的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在点击取消按钮(或右上角的 X 或 Esc)后取消退出特定表单?

How can I cancel exiting from particular form after Cancel button (or X at the top right corner, or Esc) was clicked?

WPF:

<Window
  ...
  x:Class="MyApp.MyView"
  ...
/>
  <Button Content="Cancel" Command="{Binding CancelCommand}" IsCancel="True"/>
</Window>

视图模型:

public class MyViewModel : Screen {
  private CancelCommand cancelCommand;
  public CancelCommand CancelCommand {
    get { return cancelCommand; }
  }
  public MyViewModel() {
    cancelCommand = new CancelCommand(this);
  }
}

public class CancelCommand : ICommand {

  public CancelCommand(MyViewModel viewModel) {
    this.viewModel = viewModel;
  }

  public override void Execute(object parameter) {
    if (true) { // here is a real condition
      MessageBoxResult messageBoxResult = System.Windows.MessageBox.Show(
        "Really close?",  "Warning", 
        System.Windows.MessageBoxButton.YesNo);
      if (messageBoxResult == MessageBoxResult.No) { return; }
    }
    viewModel.TryClose(false);
  }

  public override bool CanExecute(object parameter) {
    return true;
  }
}

当前代码不起作用.如果用户在弹出对话框中选择否",我希望用户保持当前表单.此外,覆盖 CanExecute 也无济于事.它只是禁用按钮.我想让用户点击按钮,然后通知他/她,数据将会丢失.也许我应该在按钮上分配一个事件侦听器?

Current code doesn't work. I want user to stay on current form if it chooses 'No' in popup dialog. Also, overriding CanExecute doesn't help. It just disables the button. I want to allow user to hit the button, but then notify him/her, that data will be lost. Maybe I should assign an event listener on button?

我设法在取消按钮上显示弹出窗口.但是我仍然无法管理 Esc 或 X 按钮(右上角).似乎我对取消按钮感到困惑,因为当我单击 X 按钮或 Esc 时会执行 Execute 方法.

I managed showing popup on Cancel button. But I still can't manage Esc or X button (top right). It seems I was confused with Cancel button, because Execute method is executed when I click X button or Esc.

编辑 2:

我改变了问题.这是如何取消取消按钮".然而,这不是我想要的.我需要取消 Esc 或 X 按钮.在MyViewModel"中,我添加:

I changed the question. It was 'how cancel Cancel button'. However, it wasn't what I was looking for. I need to cancel Esc or X button. In 'MyViewModel' I add:

        protected override void OnViewAttached(object view, object context) {
            base.OnViewAttached(view, context);
            (view as MyView).Closing += MyViewModel_Closing;
        }

        void MyViewModel_Closing(object sender, System.ComponentModel.CancelEventArgs e) {
            if (true) {
                MessageBoxResult messageBoxResult = System.Windows.MessageBox.Show(
                  "Really close?",  "Warning", 
                  System.Windows.MessageBoxButton.YesNo);
                if (messageBoxResult == MessageBoxResult.No) {
                    e.Cancel = true;
                }
            }
        }

这解决了我的问题.但是,我需要 ICommand 才能了解单击了哪个按钮,是保存还是取消.有没有办法消除事件的使用?

This solved my problem. However, I need ICommand to understand, which button was clicked, Save or Cancel. Is there any way to eliminate usage of event?

推荐答案

您正在尝试在 ViewModel 类中执行 View 的工作.让您的 View 类来处理关闭请求以及是否应该取消.

You are trying to do View's work in ViewModel class. Let your View class to handle the closing request and whether it should be canceled or not.

要取消关闭窗口,您可以订阅视图的 Closing 事件并在显示 MessageBox 后将 CancelEventArgs.Cancel 设置为 true.

To cancel closing of a window you can subscribe to the Closing event of view and set CancelEventArgs.Cancel to true after showing a MessageBox.

这是一个例子:

<Window
    ...
    x:Class="MyApp.MyView"
    Closing="OnClosing"
    ...
/>
</Window>

背后的代码:

private void OnClosing(object sender, CancelEventArgs e)
{
    var result = MessageBox.Show("Really close?",  "Warning", MessageBoxButton.YesNo);
    if (result != MessageBoxResult.Yes)
    {
        e.Cancel = true;
    }

    // OR, if triggering dialog via view-model:

    bool shouldClose = ((MyViewModel) DataContext).TryClose();
    if(!shouldClose)
    {
        e.Cancel = true;
    }
}

这篇关于如何在 MVVM WPF 应用程序中取消窗口关闭的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆