Search code examples
wpfsingletonmainwindow

How to make my WPF MainWindow a singleton?


I want to make my MainWindow a singleton because I want to make accessing it from all other windows in my app easier. But I couldn't make it run. Here is what I did.

As usual, I made the MainWindow contractor private, and created a public static MainWindow Instance property to return a static instance. When I just run it without any other changes, I got "No Source Available" error. I googled the Internet and found one related topic at http://www.netframeworkdev.com/windows-presentation-foundation-wpf/xamlc-singleton-class-80578.shtml. However, I couldn't make it work as suggested there. Some suggest to make a change in MainWindow.xaml from

<Window x:Class="TestApp.MainWindow"

to

<Window x:Class="TestApp.MainWindow.Instance"

Which looks logical. However, when I did this, I got tons of compiling errors (first one says the namespace TestApp already contains a definition of 'MainWindow'.)

I found many articles on the Internet about how to make single instance app. I'm not looking for this. I just want to make my MainWindow a singleton. I have done it in WinForm apps many times.


Solution

  • To make the MainWindow a singleton, these are the steps you need to make: Add a MainWindow Instance to MainWindow class...

    public static MainWindow Instance { get; private set; }
    

    Note: set accessor is private so that nobody else can set it to anything else.

    Add a static constructor in MainWindow and make the constructor of MainWindow private, like this...

    static MainWindow()
    {
        Instance = new MainWindow();
    }
    
    private MainWindow()
    {
        InitializeComponent();
    }
    

    Now remove StartupUri="MainWindow.xaml" from your App.xaml file so that no default window is launched when you start the application. Catch the Startup event of your App class in App.xaml.cs like this:

    public App()
    {
        ...
        Startup += App_Startup;
        ...
    }
    
    void App_Startup(object sender, StartupEventArgs e)
    {
        TestApp.MainWindow.Instance.Show();
    }