如何泛化代码以在 WPF 应用程序中每个 Window 只允许一个实例

How to generalize code to allow only one instance per Window in WPF application

注意:因为我的问题被标记为重复, 这里有更多细节: 有没有办法封装代码,而不用为每个 class 写 x 次? (这不是关于 MainWindow!这是关于多个 window classes!)

我的 WPF 应用程序包含多个 Windows(例如 Win1、Win2、Win3、..)。我希望其中一些不能同时打开多个实例。所以假设如果 Win1 已经打开并且用户单击新的 Window,我会将 Win1(仍然打开)带到 UI 的前面。 还需要可以同时打开多个(但不同Windows打开)如Win1和Win2!

我在Win1中用这个方法解决了-class:

    private static Win1 openWindow = null;

在 OnLoaded 事件中:

private void Window_Loaded(object sender, RoutedEventArgs e)
    {

        if (Win1.openWindow != null)
        {
            Win1.openWindow.Topmost = true;
            if (Win1.openWindow.WindowState == WindowState.Minimized)
                Win1.openWindow.WindowState = System.Windows.WindowState.Normal;
            Win1.openWindow.Activate();
            Win1.openWindow.Topmost = false;
            this.Close();
        }
        else Win1.openWindow = this;

最后在 OnClosing-Event 中:

    private void Window_Closing(object sender, CancelEventArgs e)
    {
       if (Win1.openWindow == this)
           Win1.openWindow = null;
    }

像其他 20 个 Win-classes 一样,我需要这种行为。有没有更好的方法来实现它,而无需每手添加 20 次? 我试着写一个自定义的Window class 并用它来继承,但是静态字段需要特定的类型(例如Win1)。

欢迎任何建议!

谢谢

@Ben Bancroft 在此处的示例中提供了解决方案:
OnlyOneOfEachTypeOfWindow-示例

正如@NPras 告诉我的,它使用 Factory-Pattern 来解决问题,主要是这里的 class:

public static class WindowManager
{
    public static T GetWindow<T>()
    {
        var t = Application.Current.Windows.OfType<T>().FirstOrDefault();
        if (t == null)
        {
            t = (T)Activator.CreateInstance(typeof(T));
        }
        return t;
    }

    public static T CreateOrFocusWindow<T>()
    {
        var t = GetWindow<T>();
        if (t is Window)
        {
            var window = t as Window;
            if (window.Visibility != Visibility.Visible)
                window.Show();
            if (window.WindowState == WindowState.Minimized)
                window.WindowState = WindowState.Normal;
            window.Focus();
        }
        return t;
    }
}

然后您可以像这样使用它:

var window = WindowManager.CreateOrFocusWindow<Window1>();
var window = WindowManager.CreateOrFocusWindow<Window2>();

感谢您的帮助!