从ViewModel打开新窗口

本文关键字:窗口 新窗口 ViewModel | 更新日期: 2023-09-27 17:57:50

我应该如何打开新窗口?我目前正在做以下工作。

EventArgs:

public class GenericViewRequestedEventArgs : EventArgs
{
    public GenericViewModel ViewModel { get; private set; }
    public GenericViewRequestedEventArgs(GenericViewModel viewModel)
    {
        ViewModel = viewModel;
    }
}

ViewModel:

public class MainWindowViewModel : ViewModelBase
{
    private RelayCommand _viewSpecificCommand;
    public ICommand ViewSpecificCommand
    {
        get
        {
            if (_viewSpecificCommand == null)
                _viewSpecificCommand = new RelayCommand(x => viewSpecific());
            return _viewSpecificCommand;
        }
    }
    public EventHandler<GenericViewRequestedEventArgs> GenericViewRequested;
    private void RaiseGenericViewRequested(GenericViewModel viewModel)
    {
        var handler = GenericViewRequested;
        if (handler != null)
            handler(this, new GenericViewRequestedEventArgs(viewModel));
    }
    private void viewSpecific()
    {
        RaiseGenericViewRequested(_specificViewModel);
    }
}

视图:

public partial class MainWindow : Window
{
    private void OnGenericViewRequested(object sender, GenericViewRequestedEventArgs e)
    {
        GenericWindow window = new GenericWindow(e.ViewModel);
        window.ShowDialog();
    }
}

这确实有效,但它似乎有很多代码,我最终在我的视图中落后了代码。

  • 将命令发送到视图模型背后的逻辑是什么
  • 是否只是选择性地使用谓词(如果是,为什么不绑定到Enabled),并可能避免将其他视图模型作为属性公开
  • 我应该在XAML中附加简单的事件处理程序吗(例如Click="btnViewSpecific_Click"

从ViewModel打开新窗口

这取决于您希望遵循MVVM模式的"严格程度"。这只是MVVM的基本陷阱之一,您可以根据自己的偏好来解决它。一种方法是简单地使用后面的代码,但您将如何处理应用程序范围的命令、键盘快捷键等?这有点太短视了。

我认为您至少应该考虑使用现有的框架,这些框架多年前就已经为您解决了这些问题,并将为您的应用程序提供坚实的基础。

例如,Catel有一个IUIVisualizerService,它可以显示基于视图模型的窗口。主要优点是可以将数据推送到视图模型中,并将结果作为服务进行响应。另一个很好的优点是,您可以模拟IUIVisualizerService,这样您就可以根据对话框提供的不同结果测试反应代码。

**免责声明**

我是Catel的开发者,所以我在这里解释了Catel的方式。如果其他人想对其他框架发表评论,请随时发表评论或创建新的答案。

是的,MVVM有很多额外的代码。构建独立于视图的命令通常用于单元测试,因此可以在不涉及UI组件的情况下对命令和ViewModel进行单元测试。

但是,如果"命令"只是打开一个窗口,则不值得创建一个命令,并对该命令进行单元测试,以查看GenericViewRequested是否真的被激发(您甚至可以检查是否返回了正确的_specificViewModel)。代码要复杂得多,只增加了很少的价值。只需在View的按钮点击事件处理程序中打开窗口,就可以了。

如果您想看到一个好的示例,请查看它在WPF应用程序框架(WAF)的ViewModel(EmailClient)示例应用程序中的工作方式。