以下问题基于这篇文章中的评论: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
我有两个问题:
- 这会破坏 MVVM 的分离吗?
- 你会怎么做(更好)?
我可以使用一些 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/