c# - MVVM 中的 Window.Closing 事件处理程序

标签 c# wpf mvvm

以下问题基于这篇文章中的评论:MVVM Understanding Issues

我说这是代码隐藏,不违反 View 和 View 模型的关注点分离:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        Closing += MainWindow_Closing;
    }

    void MainWindow_Closing(object sender, CancelEventArgs e)
    {
        var canExit = ViewModel.ShowConfirmExitDlg();
        if (!canExit) e.Cancel = true;
    }
}

评论是:

Anything in code-behind can't be unit tested, and invoking the creation of a dialog box is logic and therefore shouldn't be in the view

我有两个问题:

  1. 这会破坏 MVVM 的分离吗?
  2. 你会怎么做(更好)

我可以使用一些 EventTriggers 和 CallMethod 操作从 xaml 调用 viewmodel 方法,但这没有任何区别。

我可以使用事件聚合器:

public partial class MainWindow : Window
{
    private readonly IEventAggregator _eventAggregator;

    public MainWindow(IEventAggregator eventAggregator)
    {
        _eventAggregator = eventAggregator;
        InitializeComponent();

        Closing += MainWindow_Closing;
    }

    void MainWindow_Closing(object sender, CancelEventArgs e)
    {
        var evt = new MainWindowClosingEvent();
        _eventAggregator.Publish(evt);
        e.Cancel = evt.IsCancel;
    }
}

并在 viewmodel 中处理事件,但它是否带来任何值(value)?我仍然无法对取消 Windows 关闭事件进行单元测试,但我已经介绍了发布和订阅,这也值得进行单元测试。这是另一个间接层

也许我可以将事件路由到 viewmodel:

public MainWindow()
{
   InitializeComponent();
   Closing += ViewModel.OnWindowClosing;
   //or
   Closing += (o, e) => ViewModel.OnWindowClosing(e);
}

但我看不出与原始样本有太大区别。

恕我直言, View 和 View 模型之间的连接无法在 View 模型测试中进行单元测试,所以我要么找到一种方法来测试 View ,要么就是徒劳。

最佳答案

在我看来,这里有两个问题。首先,您可以使用交互命名空间和命令消除一些代码隐藏,以供引用:

xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"

<i:Interaction.Triggers>
  <i:EventTrigger EventName="Closing">
       ICommand goes here - bind to your VM
  </i:EventTrigger>
</i:Interaction.Triggers>

当谈到显示对话框时,您需要考虑对话框是 View 还是 View 模型。当谈到确认关闭窗口时,我认为那纯粹是一种看法。因此,您可以在 Closing 事件的代码隐藏中显示它,而无需恕我直言破坏 MVVM。

关于c# - MVVM 中的 Window.Closing 事件处理程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32253382/

相关文章:

c# - Web Api 变量参数

c# - 为什么这个事件处理程序多次抛出异常?

c# - 从列表框拖放到文本框

c# - 关于 Josh Smith 的示例应用程序的 MVVM 问题

WPF:将所有选项列表和选定选项列表绑定(bind)到带有选择复选框的列表框

c# - 如何列出所有月份名称,例如组合?

c# - 如何通过添加注册表项将用户添加到 “Access to this computer from the network” 本地策略?

wpf - WPF中的视频缩略图

c# - 从 View 模型调用方法的命令

c# - 通过网络传输 int