使用工厂方法的MVVM处理窗口管理

时间:2016-12-05 09:19:24

标签: c# wpf mvvm dependency-injection factory

我将Windows的创建(显示)委托给我的WindowFactory,它将ViewModel附加到View并显示窗口。它被注入我的MainViewModel构造函数参数。

工厂本身非常简单:

public class ProductionWindowFactory : IWindowFactory
{
    public void CreateNewWindow()
    {
        PhoneWindow window = new PhoneWindow();
        {
            window.DataContext = new phoneWindowViewModel();
        }
        window.Show();
    }
}

现在,我的目标是实现新窗口的更多功能,这将在某些按钮点击 IN 新窗口时发生。

由于我对工厂一般都很陌生,所以我很难掌握某个概念:

示例:

我们有 ViewA ,附有 ViewModelA 。 该视图有一个附加命令的按钮,告诉我们的 WindowFactory 显示一个新的 ViewB

ViewB 有一个 ViewModelB 和一个关闭按钮,告诉它关闭 ViewB

现在,由于我们不应在 ViewModelB 中引用我们的 ViewB ,因此我们必须以某种方式让它知道应该关闭哪个视图。

  

我想出了可能的想法/解决方案,但我真的会   感谢您告诉我哪一个跟随MVVM和Factory   模式“最”,在这种情况下通常使用哪一种。

  1. 让我们的 ViewModelB 将创建 ViewB 的windowFactory实例作为初始化参数,并在Factory中构建一个关闭 ViewB 并通过按钮点击执行 - >命令。
  2. 创建一个继承自 IWindowFactory IWindowManager?并构建一个WindowManager类,它扩展了 WindowFactory 的功能,并将其推入ViewModel构造函数如上所述。
  3. 任何其他正确的解决方案,我完全不知道?
  4. 请记住,以上只是一个例子。理想情况下,我想在我的窗口中实现更多高级功能,并且能够创建&使用那个工厂管理多个不同的。

    我没有附加太多代码,因为我还处于学习和决定应该使用哪种解决方案的阶段。

    编辑 - 关于可能的重复:

    我的问题与提议的副本不同,因为另一个只是关于管理关闭窗口 - 我的问题也是关于这样做,但是遵循 FactoryPattern

    我已经在我想要实现的目标中指定了非常明确的指导方针,并且在哪些方面与指出的问题完全不同。

2 个答案:

答案 0 :(得分:1)

首先,答案是 factory 的工作是创建新对象,将其视为精心设计的new运算符。此外,遵循“最”模式的想法本身也存在问题。您使用模式是因为它们可以帮助您实现某些目标,例如你使用mvvm来尽可能地避开编码ui测试,因为它们通常是脆弱的。

话虽如此,如何处理视图完全取决于视图的视图模型

示例:如果一个视图模型需要关闭其自己的窗口,请使用注释中所示的命令执行此操作。如果视图具有全按钮关闭,则其视图模型将依赖于某种窗口注册表,该窗口注册表可以枚举所有打开的窗口以关闭关闭所有命令。

在查看您的视图模型时,尝试从应用程序的其余部分想出它需要的 services ,并将这些依赖项作为接口注入。在实现接口时,很可能会有实现多个接口的类,例如WindowManager可能会实现IWindowFactoryIWindowRegistry,因此很容易将所有新创建的窗口放入打开的窗口列表中。该窗口也将依赖于IWindowRegistry,最有可能在关闭时取消注册。

答案 1 :(得分:1)

复制品并不遥远。这是对OP

中场景的简单改编
interface IView {
    void Close();
}

class ViewAdapter : IView {
    readonly Window view;
    public ViewAdapter(Window view){
        this.view = view;
    }

    public void Close() {
        view.Close();
    }
}

public class ProductionWindowFactory : IWindowFactory {
    public void CreateNewWindow() {
        var view = new PhoneWindow();
        var viewAdapter = new ViewAdapter(view)
        var viewModel = new phoneWindowViewModel(viewAdapter);

        //Bind
        view.DataContext = viewModel;

        view.Show();
    }
}

如果视图模型想要指示关闭视图,它可以要求注入的合同这样做。