Search code examples
wpfdialogwindowmodal-dialogshowdialog

Unexpected behaviour of System.Windows.Window.ShowDialog() when no other windows are open. Any idea why?


I picked up on this (with some effort) when my WPF MVVM application tried to show two consecutive error dialog windows before the main window was launched: After OKing the first window, the application went into a loop and the second error dialog never showed up.

I fixed the problem, but I was hoping someone could enlighten me as to why this happened.

It seems that, if there are no non-modal open windows, if one dialog window has been closed, all new dialog windows are immediately closed, without displaying.

Its very easy to reproduce, so here is some highly conceited code to illustrate the problem. This code is complete, so using just this, you should be able to reproduce it.

Create a Window control for the dialog window, with no code behind, and just the following XAML:

<Window x:Class="ForumExampleShowDialogIssue.OKDialogWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="OKDialogWindow" Height="300" Width="300">
<StackPanel>
    <TextBlock Text="This is a Window with a single button. The button is set to Cancel, so it closes the window."
               TextWrapping="Wrap"
               Margin="5"/>
    <Button Content="OK" IsCancel="True" IsDefault="True"
            Margin="5"/>
</StackPanel>

Next, use the standard WPF App class, with nothing new in the XAML, but with the following in the code behind:

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

    OKDialogWindow alwaysOpen = new OKDialogWindow();
    alwaysOpen.Show();

    while (true)
    {                
        OKDialogWindow dialogWindow = new OKDialogWindow();
        Console.WriteLine("Before show");
        dialogWindow.ShowDialog();
        Console.WriteLine("After show");
    }
}

Delete the MainWindow.XAML if it exists, and remove the reference to it from the App.XAML header.

Run. (the program, not like Forest).

This works as expected. The alwaysOpen window remains open, while one after the other dialogWindow instances appear in dialog mode, closing when OK is clicked, then showing the next one.

HOWEVER, this breaks when you change OnStartup to the following:

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

    while (true)
    {                
        OKDialogWindow dialogWindow = new OKDialogWindow();
        Console.WriteLine("Before show");
        dialogWindow.ShowDialog();
        Console.WriteLine("After show");
    }

}

When there is no constantly open window, the first dialog window is the only one that works. After that, countless "Before show" and "After show" messages are printed to the console, but no new dialog windows appear - they are closed automatically as soon as they are shown.

Surely this can't be the intended behaviour? Do you get the same result? Any idea why this happens?


Solution

  • This is the intended behavior.

    • by Default the first open window is the MainWindow.
    • By default the only window in the list becomes the MainWindow (if others are to be removed).
    • Application Class is designed to exit if no windows are present in windows list.

    Check this: http://www.ageektrapped.com/blog/the-wpf-application-class-overview-and-gotcha/