Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why would Window.Close event propagate?

Tags:

c#

wpf

I ran into a weird case where Close event of the child window propagate to the parent window and causes it to close as well.

I made a minimum example as shown below

For TestWindow there is nothing but the default WPF window generated by VS

and in App.xaml.cs I override the OnStartup event and use it as a custom Main function

protected override void OnStartup(StartupEventArgs e)
{
    base.OnStartup(e);

    TestWindow t = new TestWindow();
    t.ShowDialog();
}

Now if you click on the X button to close TestWindow, the application shuts down instead of showing the MainWindow. If you comment out t.ShowDialog then the MainWindow will show just fine. Next if you listen to the Closing event of MainWindow you will find that it will trigger after the TestWindow closes which doesn't seem right to me

like image 695
Steve Avatar asked Oct 10 '15 00:10

Steve


1 Answers

It's not actually propagating, WPF runs your first dialog and upon closing notices that the process has no further windows present. WPF posts an application quit message for later processing. In the meantime your code has proceeded to display a further window which when processing the message pump encounters the quit message and so closes the window and terminates your app.

Debug log:

Information: 0 : App OnStartup

Information: 0 : new MainWindow

Information: 0 : MainWindow closing

Information: 0 : App exiting

To resolve, you need to remove the StartupUri and instead handle the Startup event.

Change:

<Application x:Class="WpfCloseProblem.App"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:local="clr-namespace:WpfCloseProblem"
         StartupUri="MainWindow.xaml"> ...

...to:

<Application x:Class="WpfCloseProblem.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:WpfCloseProblem"
             Startup="Application_Startup">

Then discard the code on OnStartup and instead define a handler for Startup:

//protected override void OnStartup(StartupEventArgs e)
//{
//    base.OnStartup(e);
//
//    TestWindow t = new TestWindow();
//    t.ShowDialog();
//}

private void Application_Startup(object sender, StartupEventArgs e)
{
    var main = new MainWindow();

    TestWindow t = new TestWindow();
    t.ShowDialog();

    main.Show();
}

Previously I was able to confirm that after the dialog closed, MainWindow was created; loaded and closed in quick succession.

like image 89
MickyD Avatar answered Sep 27 '22 23:09

MickyD