想象一下,您想要在精美的 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/