实例化和显示依赖于当前 window 中所选值的 window 的正确模式是什么?

What is the proper pattern for instantiating and showing a window that relies on a value selected in the current window?

使用依赖注入原则和 DI 容器,启动需要在父 window 中进行选择作为依赖的子对话框的正确模式是什么?示例:Select 主 window 列表中的一个 PersonViewModel,然后单击按钮启动详细信息 window。详细信息 window 需要传递给它的 PersonViewModel 以提供 DataContext。

我发现的两种方法:

  1. 将子 window 作为依赖项传入,并在调用 ShowDialog 之前使用 属性 注入提供子 window 依赖项。
  2. 传入用于解析子 window 的 ViewFactory,并在调用 ShowDialog 之前使用 属性 注入提供子 window 依赖项。

我正在寻找的是一个普遍接受的可测试模式。我发现的所有 DI 示例似乎都只有一层深,或者不需要在父 window 中选择依赖项。

谢谢!

我建议使用不同的方法。我建议这样做的方法是创建一个用于显示对话框 window 的小型管理器对象,通过它您可以在用于创建之前将参数传递给对话框 window 的视图模型window 本身。

为您的 window 和视图模型创建工厂,并像这样使用它们:

public class DetailsWindowDisplayer : IDetailsWindowDisplayer
{
    private readonly IDetailsWindowFactory windowFactory;
    private readonly IDetailsWindowViewModelFactory viewModelFactory;

    public DetailsWindowDisplayer(
        IDetailsWindowFactory windowFactory,
        IDetailsWindowViewModelFactory viewModelFactory)
    {
        this.windowFactory = windowFactory;
        this.viewModelFactory = viewModelFactory;
    }

    public void ShowDetails(IPersonViewModel personViewModel)
    {
        var windowViewModel = this.viewModelFactory.Create(personViewModel);
        var window = this.windowFactory.Create(windowViewModel);
        window.Show();
    }
}

然后是将IDetailsWindowDisplayer注入父视图模型并调用ShowDetails方法的简单情况。这将对话框的显示抽象为单个调用,DetailsWindowDisplayer 只有一个责任。

为了使其完全可测试,您的 window 工厂应该 return 一个接口。您可以使用以下层次结构执行此操作:

public interface IDialogWindow
{
    void Show();
}

public interface IDetailsWindow : IDialogWindow
{
}

public class DetailsWindow : Window, IDetailsWindow
{
    // The Show() method from IDialogWindow is automatically implemented
    // by the WPF Window class
}

如果您希望将详细信息 window 保持为单例,您可以将 window 注入到 DetailsWindowDisplayer 的构造函数中,或者 1. 设置一个新的视图模型每次显示它时,或者 2. 也将其视图模型设为单例,将 ViewModel 属性 放在 window 和 Person 属性 上到视图模型,然后每次都将 Person 设置为新的 PersonViewModel 实例。

一般来说,我倾向于不使用容器来解析视图。 有几个项目专门用于以非常好的方式进行 View-ViewModel 绑定。

我建议您在 Caliburn.Micro 上查看 UI 内容,并将容器用于所有其他依赖项注入。如果您在使用 Windsor 设置 Caliburn.Micro 方面需要任何帮助,请告诉我。