问题
It says, I can use Startup event for many things, like initialization, creating multiple forms, blablabla.
However, try to create a new WPF application and add this event handler:
private void App_Startup(object sender, StartupEventArgs e)
{
Window window = new Window();
}
And after closing main window your application will hang up in the memory. Pausing executing in VS at that moment will drop ugly crash call stack window with a lot of calls somewhere far away from my source code.
Any thoughts?
P.S.: I need to instantiate all of my windows for self-learning configuration purpose once. Should I use some other place?
Let me give a better example (example above is good to reproduce the problem, seems it's hard to understand what I am actually doing). I remove StartupUri and then:
private void App_Startup(object sender, StartupEventArgs e)
{
// un-comment this line to reproduce the problem:
// Window window = new Window();
// actual implementation will be
// Window1 window1 = new Window1();
// Window2 window2 = new Window2();
// Window3 window3 = new Window3();
// Window4 window4 = new Window4();
// ...
// start main window as usually
MainWindow mainWindow = new MainWindow();
mainWindow.Show();
}
And why do I need instances of windows (window1, ..2, ..3, ...)? Because their content will be inspected to create a list of controls for which I want to save configuration. Some of these windows will never be shown to the user (to example, if he is not admin), some of them are popups, some are editors, etc. So I do not want to display them. But at any application startup the configuration has to be created and saved. And I am looking now for the place to do so.
Surprisingly, using dedicated event Startup seems have some problems with creating multiple windows but not displaying them. Question is why and how to solve it.
Testing a bit more. Try this code and explain me, why application is closed without showing any window?
private void App_Startup(object sender, StartupEventArgs e)
{
Window window = new Window();
window.Close(); // closing without opening window
MainWindow mainWindow = new MainWindow();
mainWindow.Show();
//mainWindow = new MainWindow(); // can be un-commented, for absolutely no effect
mainWindow.Show();
mainWindow.Show();
mainWindow.Show();
mainWindow.Show(); // you will not see mainWindow at all, all Show doing nothing
}
More questions. What do I do?
Something what works, but smells:
private void App_Startup(object sender, StartupEventArgs e)
{
Window window = new Window();
MainWindow mainWindow = new MainWindow();
mainWindow.ShowDialog();
Shutdown();
}
Notice, calling ShowDialog (which will make event handler waiting for that window closing) and calling Shutdown right after.
It is still not clear what is the problem in the Startup event handler to create instances of some windows. Any ideas?
回答1:
By doing this, the window you just created has become the main window: the one specified in StartupUri will only be created right after the start up event. By default, the main window must be closed for the application to shutdown. Since it's never shown, the user has no opportunity to do this and the application seems to hang forever. What you're seeing when the execution is paused is a normal message loop, there is no crash here. Add window.Show() to see your real 'main' window.
Remove the StartupUri attribute from your App.xaml if you decide to instantiate the main window manually. Alternatively, keep the attribute and instantiate the additional windows after the Loaded event from the main window has been fired.
回答2:
I have solution, which seems pretty good to me. Idea is similar to winforms - do everything in the Main.
This, however, is a bit tricky in wpf (I used this question as a guide):
- Remove
StartupUrifromApp.xaml; - Set
App.xamlpropertyBuild ActiontoPage(this sounds strange, but it works for desktop application). This will removeMainmethod from auto-generated classes (App.g.cs and App.g.i.cs). - Add
Mainmethod manually intoApplication:
.
public partial class App : Application
{
[STAThread]
public static void Main()
{
Window window1 = new Window();
Window window2 = new Window();
Window window3 = new Window();
// ...
MainWindow start = new MainWindow();
start.ShowDialog();
SomeOtherWindow next = new MainWindow();
next.ShowDialog();
}
}
Now I can directly control which window to show and when (program flow control), as well as there is no more bug with not-closing application when creating instances of windows without displaying them.
The suspicious things are this Page setting and that fact, what I do not instantiate Application, nor I call Run(). I do not know yet, if it will be a problem in the future. Would be nice to know it for sure.
It might be necessary to init application still (to load resources?), then
[STAThread]
public static void Main()
{
App app = new App();
app.InitializeComponents();
// ... the rest
// possibly app.MainWindow = start; or app.MainWindow = next;
// if only 1 window, then app.Run(new MainWindow());
}
来源:https://stackoverflow.com/questions/22460116/application-startup-event-limitations-bug