C# WPF how to enforce single instances of windows C# WPF how to enforce single instances of windows wpf wpf

C# WPF how to enforce single instances of windows


there are probably better ways to do this, but here is a relatively simple way....put a static bool on your window class to flag if its open or not. then, in the load() event set it to true, and on the close event set it to false. Then, in the code that opens the window, check the flag.

here is some pseudo-code to give you an idea...

public class AboutWindow{    public static bool IsOpen {get;private set;}    onLoadEvent(....)     {        IsOpen = true;    }    onUnloadEvent(...)     {        IsOpen = false;    }}public void OpenAbout(){    if ( AboutWindow.IsOpen ) return;    AboutWindow win = new AboutWindow();    win.Show();}


If you truly need to enforce a single instance of a window, then a static instance (some flavor of what you have) with a factory creation method is certainly a viable option, much like a single DataContext instance when working with a database.

You could also write your own WindowManager class, although that seems like overkill, and will essentially be the same thing (except the Factory methods would be in a single class).

However, re-reading your post, I wonder if this is a case of missing the forest for the trees. Your mentioning of your SettingsWindow, which in turn calls AccountWindow, makes me think that you should simply be using ShowDialog(). This opens a window modally, meaning that there can be no interaction with the calling window (or any other window in your application). You simply set a property in that dialog, set the DialogResult to true when the OK button is pressed, and read that property in the parent window.

Basically, you just use the ShowDialog like this. I am leaving out a lot of the implementation details, as far as binding vs. hard-coding to controls. Those details aren't as important as just seeing how ShowDialog works.

For simplicity, assume that you have a class called MyAppOptions that, well, reflect the options of your application. I will leave off most of the implementation details of this for simplicity, but it would likely implement INotifyPropertyChanged, have methods and fields and properties, etc.

public class MyAppOptions{    public MyAppOptions()    {    }    public Boolean MyBooleanOption    {        get;        set;    }    public String MyStringOption    {        get;        set;    }}

Then, let's make this simple, and assume that you want to show an Options dialog when you press a button on some window. Furthermore, I will assume that there are variables that have been set with your options, which were loaded at startup.

void btnOptions_Click(object sender, RoutedEventArgs e){    MyAppOptions options = new MyAppOptions();    options.MyBooleanOption = mSomeBoolean;    options.MyStringOption = mSomeString;    OptionsDialog optionsDialog = new optionsDialog(options);    if (optionsDialog.ShowDialog() == true)    {        // Assume this function saves the options to storage        // and updates the application (binding) appropriately        SetAndSaveOptions(optionsDialog.AppOptions);    }}

Now assume that the OptionsDialog is a window you've created in your project, and it has a CheckBox on it related to MyBooleanOption and a TextBox for MyStringOption. It also has an Ok button and a Cancel button. The code-behind will likely use Binding, but for now we'll hard code the values.

public class OptionsDialog : Window{    public OptionsDialog(MyAppOptions options)    {        chkBooleanOption.IsChecked = options.SomeBooleanOption;        txtStringOption.Text = options.SomeStringOption;        btnOK.Click += new RoutedEventHandler(btnOK_Click);        btnCancel.Click += new RoutedEventHandler(btnCancel_Click);    }    public MyAppOptions AppOptions    {        get;        set;    }    void btnOK_Click(object sender, RoutedEventArgs e)    {        this.AppOptions.SomeBooleanOption = (Boolean) chkBooleanOption.IsChecked;        this.AppOptions.SomeStringOption = txtStringOption.Text;        // this is the key step - it will close the dialog and return         // true to ShowDialog        this.DialogResult = true;    }    void btnClose_Click(object sender, RoutedEventArgs e)    {        // this will close the dialog and return false to ShowDialog        // Note that pressing the X button will also return false to ShowDialog        this.DialogResult = false;    }}

This is a pretty basic example as far as implementation details. Search online for ShowDialog for more details. The important keys to remember are:

  • ShowDialog opens a window modally,meaning it is the only window in yourapplication that can be interactedwith.
  • Setting DialogResult to truewill close the dialog, which can bechecked for from the calling parent.
  • Setting DialogResult to false willalso close the dialog, in which caseyou skip updating the values in thecalling window.
  • Pressing the X buttonon the window automatically sets theDialogResult to false
  • You can have public properties in the dialog window that can be set before doing the ShowDialog, and can get values from after the dialog disappears. It will be available while the dialog is still in scope.


The following extends on the above solution to reshow the window if it is already open. In this case it is a help window.

    ///<summary>    /// Show help from the resources for a particular control by contextGUID    ///</summary>    ///<param name="contextGUID"></param>    private void ShowApplicationHelp(string contextGUID = "1")    {        if (HelpWin != null)        {            if (HelpWin.IsOpen)            {                HelpWin.BringToFront();                return;            }        }        HelpWin = new MigratorHelpWindow();        HelpWin.Owner = Application.Current.MainWindow;        HelpWin.ResizeMode = ResizeMode.CanResizeWithGrip;        HelpWin.Icon = new Image()                           {                               Source =                                   new BitmapImage(                                   new Uri(                                       "pack://application:,,,/ResourceLibrary;component/Resources/Images/Menu/Help.png",                                       UriKind.RelativeOrAbsolute))                           };        HelpWin.Show();        HelpWin.BringToFront();    }

This code is all in a viewmodel (MVVM) associated with the window. It is called by an ICommand hooked to a button on the window (naturally, it shows a question mark!!)The following property is involved (in this case it is a Telerik RadWindow but it can be any window object, and you can probably also just store the window handle but using this property permits manipulation of the object more smoothly e.g. HelpWin.BringToFront() as in the above example...

    ...    ...    private Telerik.Windows.Controls.RadWindow **HelpWin**    {        get;        set;    }    ...    ...

In the window itself (WPF window)

    ///<summary>    /// Flag to indicate the window is open - use to prevent opening this particular help window multiple times...    ///</summary>    public static bool IsOpen { get; private set; }    ...    ...    ...  private void HelpWindowLoaded(object sender, RoutedEventArgs e)    {        IsOpen = true;    }    private void HelpWindowUnloaded(object sender, RoutedEventArgs e)    {        IsOpen = false;    }

and in the view Xaml ... ...

  DataContext="{Binding Path=OnlineHelpViewModelStatic,Source={StaticResource Locator}}"   RestoreMinimizedLocation="True"   **Loaded="HelpWindowLoaded" Unloaded="HelpWindowUnloaded"** >