简体   繁体   中英

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

Note : Because my question got flagged as duplicate, here some more details: Is there a way to encapsulate the code, without writing it x-times for every class? (It's not about the MainWindow! It's about multiple window classes!)

My WPF-Application contains multiple Windows (eg Win1, Win2, Win3, ..). I want that some of them can't open multiple instances at the same time. So let's say if Win1 is allready open and the user clicks for a new Window, I will bring the Win1 (which is still open) to the front of the UI. It is also needed that it's possible to have multiple (but different Windows open) like Win1 and Win2 are open at the same time!

I solved it with this approach in the Win1-class:

    private static Win1 openWindow = null;

In the OnLoaded-Event:

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;

And finally in the OnClosing-Event:

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

I need this behavoir in like 20 other Win-classes. Is there a better way how I could implement it, without adding it 20-times per hand? I tried to write a custom Window class and use it for inheritance, but the static field needs the specific type (eg Win1).

Any advices welcome!

Thank you

The solution was provided by @Ben Bancroft in his example here:
OnlyOneOfEachTypeOfWindow-Example

As @NPras told me, it uses the Factory -Pattern to solve the problem, mainly with the class here:

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;
    }
}

You can then use it like:

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

Thanks for the help!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM