1

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?

Call stack


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?

Sinatr
  • 20,892
  • 15
  • 90
  • 319

2 Answers2

3

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.

Julien Lebosquain
  • 40,639
  • 8
  • 105
  • 117
  • Ok, I removed `StartupUri` and starting main window in `Startup` event **after** that row (which creates `Window` instance). Still application halts when closing **main** window. – Sinatr Mar 18 '14 at 09:24
  • Regarding `Loaded` event, do you know where can I see the order of events? Because if I read it right, [`Loaded`](http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.loaded.aspx) is when element is rendered, which for me sounds like `shown first timer` event. But, as I said, I am not willing to display that form at all. It is interesting, does any of upvoters bother to reproduce the problem? – Sinatr Mar 18 '14 at 09:50
  • I don't understand what you mean by "after" that row. You should remove the StartupUri in the .xaml file. Add Show() calls for testing purposes to see the created windows. You'll notice one is still opened. Yes, Loaded is when the element is rendered, use the first solution instead (startup event without StartupUri in the App.xaml file). – Julien Lebosquain Mar 18 '14 at 10:43
  • See question edit. Yes, I removed `StartupUri` in .xaml file. And yes, it will **work** if I add `Show` for each instantiated window. Now, how to make application working **without showing windows** (I mentioned this many time)? Regarding `Loaded`, when exactly does it triggers? Will it trigger when I instantiate or just before displaying? But displaying means *show window* and if you read me accurately, this is **not what I want**. Question is still opened: why instantiating window (without showing it) in `Startup` event **is a problem** and what to do to fix it? – Sinatr Mar 18 '14 at 10:52
  • It's not a problem, it's the default behavior! If you don't want to wait for the main window to be closed for the application to shutdown (because you *chose* to hide the said window), please call `Application.Shutdown` manually when you feel it's the right time. For example, when a specific window has been closed. Indeed, `Loaded` triggers just before displaying so that won't work for your case. – Julien Lebosquain Mar 18 '14 at 12:27
  • I don't understand that *default behavior*. I create instance of some class in event handler. **What is the problem** with that? Idea with `Application.Shutdown` is not bad, see edit. – Sinatr Mar 18 '14 at 13:20
1

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 StartupUri from App.xaml;
  • Set App.xaml property Build Action to Page (this sounds strange, but it works for desktop application). This will remove Main method from auto-generated classes (App.g.cs and App.g.i.cs).
  • Add Main method manually into Application:

.

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());
    }
Community
  • 1
  • 1
Sinatr
  • 20,892
  • 15
  • 90
  • 319