ShowDialog() ends prematurely if called from hidden windows

1.9k views Asked by At

Consider this code:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        Title = DateTime.Now.ToString();
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        Hide();
        new MainWindow().ShowDialog();
        Show();
        Debug.WriteLine(Title);
    }
}

The XAML is trivial:

<Window x:Class="ShowHide.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid>
        <Button
            Content="Test"
            HorizontalAlignment="Left"
            VerticalAlignment="Top"
            Click="Button_Click"/>
    </Grid>
</Window>

If I go "up", it works as expected - this window gets hidden, the new one is created and is shown as a modal window. But when I close the currently visible window, all hidden windows "underneath" get shown at once and they're not modal anymore. Multiple lines appear in the output window.

However, if I comment out the Hide() call, the problem doesn't seem to arise, i.e. I get to close modal windows one by one in reverse.

To reproduce:

  1. Run the code.
  2. Press the "Test" button. The current window will hide and the new one will appear.
  3. Press the "Test" button in the new window. Another window will be created again. You can repeat this step as many times as you want.
  4. Close the window. Older windows will re-appear all at once and neither will be modal.

Is this by design? What would your workaround be?

2

There are 2 answers

0
Bolu On BEST ANSWER

This is by design, as you hide your Modal window and display it again using Show() rather than ShowDialog(), so you could modify your code as below:

bool isChild;

private void Button_Click(object sender, RoutedEventArgs e)
{
    Hide();
    new MainWindow() { isChild = true }.ShowDialog();

    if (isChild)
    {
        ShowDialog();
    }
    else
    {
        Show();
    }
}
0
StepUp On

The code works just as you write. You call a method Show(), but you should write ShowDialog(). Just change this code:

 Hide();
 new MainWindow().ShowDialog();
 Show();

To:

  Hide();
 new MainWindow().ShowDialog();
 ShowDialog();