将M-V-VM与WPF一起使用,如何在给定ViewModel的情况下实例化对话视图?

时间:2009-12-07 17:56:33

标签: c# wpf mvvm dialog

我正在使用M-V-VM和对话框。我用于创建对话框的过程如下:

  • ViewModel命令希望打开一个对话框。
  • 它为对话框创建ViewModel(我们称之为DialogViewModel)。
  • 然后将ViewModel传递给DialogProvider以创建实际的View。这使我的对话框可测试,因为提供者可以提供真实视图或测试视图。

我把这一切都搞定了。但是,目前我对DialogProvider的解决方案是使用反射来手动查找要根据ViewModel名称实例化的View类,如下所示:

var viewModelType = viewModel.GetType();
var dialogTypeName = Regex.Replace(viewModelType.Name, "ViewModel$", "Dialog");
var viewType = Assembly.GetExecutingAssembly().GetType(dialogTypeName);
if (viewType == null)
    throw new InvalidOperationException("Could not find view for given type.");

var dialog = (Dialog)viewType.GetConstructor(Type.EmptyTypes).Invoke(new object[0]);
dialog.DataContext = viewModel;
dialog.Owner = Application.Current.MainWindow;

return dialog;

这不是最理想的,因为View必须与ViewModel命名相同,并且必须位于相同的命名空间中等。

理想情况下,我会使用DataTemplate机制来执行此操作。我想要做的就像在视图中使用DataTemplate一样,并使用ContentPresenter根据DataTemplate的DataType属性选择视图(参见Josh Smith's MVVM article。但是,我需要在C#代码中执行此操作(在DialogProvider中。)

这可能吗?我想象的事情就像在C#中创建一个ContentPresenter,设置它的DataTemplate,然后到达它以拉出Dialog视图???

埃里克

2 个答案:

答案 0 :(得分:3)

为什么不让DialogProvider使用默认的View,它只是一个包含ContentPresenter的窗口。

然后,您可以将窗口资源与当前窗口资源合并(这会让新ViewModel的DataTemplate映射到相应的View,定义为UserControl)。

完成后,您所要做的就是将C#中的ContentPresenter的内容设置为DialogViewModel,WPF会处理将适当的View映射到位。

答案 1 :(得分:1)

我们使用依赖注入(DI)来获取指定ViewModel的View(或Dialog)。这种方法让我们用MockView对ViewModels进行单元测试。