Open a Single Instance of Window in WPF

2019-08-15


We often need to limit some Windows in a system to allow only one open each time. If you want to open another instance of the Window, you must first close the opened one; on the other hand, if the opened Window instance is not closed, you cannot open a new instance of the same Window.

For example, we have a search Window, and every time we need to have only one search window open in a running system.

You might say we can show window modally, like the code below:

srchWin.ShowDialog()

But in our case we have to use Modeless dialog, We have to interact with the rest of the same UI with the Seach window open.

In the existing system, there are already multiple places to call to open this window, we can not change the code of those calls one by one:

SearchWin srchWin = new SearchWin();
srchWin.Show(); //modeless dialog

The best way is to change the code inside the window class, to do the smallest change, also it is most convenient.

Then we think of a feasible way is to use Singleton, only one instance is allowed to open in the system.

How did we do to get single instance of the window?

In the Search Window code-behind class, we added the code below:

public static SearchWin Current { get; private set; } //singleton

Then in the Windows Loaded event, we added:

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            if (Current != null)
            {
                this.Close();  //if old instance exists, close the new instance
				
                if(!Current.IsActive)
                    Current.Activate();

                if (!Current.IsFocused)
                    Current.Focus();
            }
            else
            {
                Current = this;  //a new instance
            }

           //...
           //...
        }

If the user closes the window, we will set the matched instance pointer to null:

   private void Window_Closed(object sender, EventArgs e)
   {
         //...
         //...
         //...

         // If user closes the window -- this is the new instance, Current is the old one
         if ((Current == this) && (Current != null))
             Current = null;
   }