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 s开发者_如何学JAVAingle 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.
Not sure about making it singleton, but why would you want to? You can simple use Application.Current.MainWindow to get the Application.MainWindow property anytime from anywhere in your application.. See: http://msdn.microsoft.com/en-us/library/system.windows.application.mainwindow(v=VS.90).aspx.
Window mainWin = Application.Current.MainWindow;
mainWin.Title = "This will be set as the title of the Main Window";
Making it singleton still does not make sense to me - how does that make it more accessible? You can always save reference to your main window in a public static variable - this could be set in the constructor of your main Window:
public partial class MainWindow : Window
{
public static MainWindow myMainWindow; // ASSUMPTION: only one MainWindow is ever constructed otherwise this will be overwritten by latest such instance
public MainWindow()
{
InitializeComponent();
myMainWindow = this;
}
}
But then given the above Application.Current.MainWindow why bother..
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();
}
Remove StartupUri="MainWindow.xaml"
from your App.xaml file. WPF will not launch any window for you anymore.
<Application x:Class="WpfApplication1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
</Application>
Add a handler to the Startup
event of your App
class in App.xaml.cs.
In this handler call the Show()
method of your singleton instance.
using System;
using System.Windows;
namespace WpfApplication1
{
public partial class App : Application
{
public App()
{
Startup += new StartupEventHandler(App_Startup);
}
void App_Startup(object sender, StartupEventArgs e)
{
WpfApplication1.MainWindow.Instance.Show();
}
}
}
Note: The App
class has a property called MainWindow
, hence in App_Startup()
I prefixed the MainWindow
class with the namespace!
Thank you all very much for the quick answsers. The key point is that I have to remove StartupUri="MainWindow.xaml"
from App.xaml. Thanks also for the tip of static contructor. Another point I want to mention is that we can also override OnStartup to startup the main window (just to make a few lines shorter):
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
TestApp.MainWindow.Instance.Show();
}
}
精彩评论