c# - MVVM:代码隐藏是邪恶的还是实用主义的?

标签 c# wpf mvvm data-binding code-behind

想象一下,您想要在精美的 WPF MVVM 窗口上有一个Save & Close 和一个Cancel & Close 按钮吗?

你会怎么做? MVVM 指示您将按钮绑定(bind)到 ICommand,而控制反转指示您的 View 可能知道您的 ViewModel 但不是相反。

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

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 的混合。

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

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

最佳答案

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

interface IClosable
{
    void Close();
}

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

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

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

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

最后,命令调用 Close:

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

我们现在有什么?

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

关于c# - MVVM:代码隐藏是邪恶的还是实用主义的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40257513/

相关文章:

c# MultipartFormDataContent 添加方法(如何正确添加文件)

c# - C# 安装应用程序中的 Google OAuth 2.0 身份验证

c# - 如何删除 WPF 中 ListView 中显示的特定文本?

c# - 使用 linq 表达式将 IsEnabled 绑定(bind)到 linq 属性

c# - 绑定(bind)到已设置选定项目的 View 模型时,无法让 telerik radgridview 突出显示 SelectedItem

c# - MVVM: View 导航无法正常工作

c# - 系统.IO.IOException : The process cannot access the file 'file_name'

c# - .NET Core 中 HttpWebRequest.GetRequestStream 返回的流不会立即发送数据

wpf - 如何在 WPF 中将 UIElements(按钮)的 "isfocusable"属性设置为 false?

wpf - ListView 不显示 ListView 项目