【问题标题】:Using M-V-VM with WPF, how do I instantiate a Dialog View given a ViewModel?将 M-V-VM 与 WPF 一起使用,如何在给定 ViewModel 的情况下实例化对话框视图?
【发布时间】:2009-12-07 17:56:32
【问题描述】:

我正在使用带有对话框的 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 视图???

埃里克

【问题讨论】:

    标签: c# wpf mvvm dialog


    【解决方案1】:

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

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

    完成此操作后,您只需从 C# 将 ContentPresenter 的内容设置为 DialogViewModel,然后 WPF 会处理将适当的视图映射到位。

    【讨论】:

    • 好的。知道了。这样可行。对尝试此操作的其他人的警告:不要忘记在对话窗口上设置 Owner 属性。如果不这样做,WPF 将找不到 DataTemplate 的资源,因此您会得到一个对话框窗口,其中包含 ViewModel 的类型名称而不是相应的 View。
    • Reed - 遇到了问题。如何从 DataTemplate 设置对话框窗口的标题和大小?埃里克
    • 对于标题:您需要从 DialogProvider 执行此操作,而不是通过 DataTemplate。可以通过将其设置为 auto 来处理大小 - 并且只需适当调整 UserControl 的大小。
    【解决方案2】:

    我们使用依赖注入 (DI) 来获取指定 ViewModel 的视图(或对话框)。这种方法让我们可以使用 MockView 对 ViewModel 进行单元测试。

    【讨论】:

      猜你喜欢
      • 2010-09-30
      • 1970-01-01
      • 2013-08-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多