MVVM:代码隐藏是邪恶的还是务实的? [英] MVVM: Is code-behind evil or just pragmatic?

查看:13
本文介绍了MVVM:代码隐藏是邪恶的还是务实的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

想象一下你想要一个 Save &关闭Cancel &在您喜欢的 WPF MVVM 窗口上关闭按钮?

Imagine you want a Save & Close and a Cancel & Close button on your fancy WPF MVVM window?

你会怎么做?MVVM 规定您将按钮绑定到 ICommand 并且控制反转规定您的 View 可能知道您的 ViewModel 但不知道相反.

How would you go about it? MVVM dictates that you bind the button to an ICommand and inversion of control dictates that your View may know your ViewModel but not the other way around.

在网上搜索我找到了一个解决方案,它有一个 ViewModel 关闭事件,View 像这样订阅:

Poking around the net I found a solution that has a ViewModel closing event to which the View subscribes to like this:

private void OnLoaded(Object sender
    , RoutedEventArgs e)
{
    IFilterViewModel viewModel = (IFilterViewModel)DataContext;
    viewModel.Closing += OnViewModelClosing;
}

private void OnViewModelClosing(Object sender
    , EventArgs<Result> e)
{
    IFilterViewModel viewModel = (IFilterViewModel)DataContext;
    viewModel.Closing -= OnViewModelClosing;
    DialogResult = (e.Value == Result.OK) ? true : false;
    Close();
}

但这是与我迄今为止设计良好的 MVVM 混合在一起的代码隐藏.

But that is code-behind mixed in with my so far very well designed MVVM.

另一个问题是在显示主窗口时显示许可问题消息框.我再次可以像上面那样使用 Window.Loaded 事件,但这也破坏了 MVVM,不是吗?

Another problem would be showing a licensing problem message box upon showing the main window. Again I could use the Window.Loaded event like I did above, but that's also breaking MVVM, is it not?

在这些情况下,是否有一种干净的方法或者应该务实而不是迂腐?

Is there a clean way or should one be pragmatical instead of pedantic in these cases?

推荐答案

首先,创建一个只包含Close方法的接口:

First, create an interface that contains only the Close method:

interface IClosable
{
    void Close();
}

接下来,让你的窗口实现IClosable:

Next, make your window implement IClosable:

class MyWindow : Window, IClosable
{
    public MyWindow()
    {
        InitializeComponent();
    }
}

然后让视图将自身作为 IClosable 作为命令参数传递给视图模型:

Then let the view pass itself as IClosable as command parameter to the view model:

<Button Command="{Binding CloseCommand}" CommandParameter="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}}" />

最后,命令调用Close:

CloseCommand = new DelegateCommand<IClosable>( view => view.Close() );

我们现在有什么?

  • 我们有一个关闭窗口的按钮
  • 我们在代码隐藏中没有代码除了 ,IClosable
  • 视图模型对视图一无所知,它只是获取可以关闭的任意对象
  • 该命令可以轻松地进行单元测试

这篇关于MVVM:代码隐藏是邪恶的还是务实的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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