4

我已经阅读了 WPF(和一般的 GUI)的一个很好的做法,说要打开尽可能少的窗口。但有时,你根本没有选择。

所以我想到了一个快速优雅的解决方案来打开一个新窗口,我想到了这个:

public static class WinManager
{
    private static Dictionary<Type, Func<Window>> collection 
        = new Dictionary<Type, Func<Window>>();

    /* Bind the type of the ViewModel with a lambda that build an 
     * instance of a window*/
    public static void Bind(Func<Window> ctor, Type type) { ... }

    /* Search in the dictionary the specified type and show the window 
     * returned by the lambda*/
    public static void Show(Type type){ ... }

    /* Search in the dictionary the specified type and show the dialogue
     * returned by the lambda*/
    public static void ShowDialog(Type type) { ... }
}

type是绑定到视图(即窗口)的 ViewModel 的类型,lambdactor用于返回窗口的新实例。

像这样管理窗口是个好主意还是我完全错了?

4

2 回答 2

2

我认为这是一个不错的主意。

它的优点是想要显示另一个窗口的 ViewModel 不必使用任何 WPF 特定代码,甚至不需要知道视图。它只需要知道要为其显示窗口的 ViewModel。这与Caliburn.Micros 非常相似IWindowManager

我不喜欢这个解决方案的一点是类的静态性质。这使得单元测试变得困难(呃)。如果您使用依赖注入,您可以创建一个接口和该接口的实现,类似于您的静态类。然后,您可以在组合根中创建该类的实例,将 ViewModel 类型绑定到 lambda View 工厂并将该实例注册到您的 DI 容器。每个想要显示另一个窗口的 ViewModel 现在都依赖于该接口,这使得它在单元测试中很容易模拟。

像这样的东西:

interface IWindowManager
{
    void Show(Type type);
    void Show<T>();
    void ShowDialog(Type type);
    void ShowDialog<T>();
}

class WindowManager : IWindowManager
{
    // Implementation of the four methods from the interface plus:

    private Dictionary<Type, Func<Window>> collection 
        = new Dictionary<Type, Func<Window>>();

    public void Bind(Func<Window> ctor, Type type) { ... }
}

Bind仅在具体实现上使用该方法WindowManager的好处是IWindowManager用户无法更改注册。

于 2012-04-19T09:19:38.250 回答
2

这不是一个坏主意,实际上我在我的个人项目中使用的是相同的,并且效果很好:)

WindowManager中,您可以跟踪屏幕上可见的所有打开的表单,管理它们的外观和视觉关系(如果另一个也被隐藏,则隐藏一个,诸如此类)。

于 2012-04-19T09:23:30.000 回答