Tuesday, June 20, 2017

Why does closing the last child window minimize its parent window?

Leave a Comment

I have the following simple wpf application:

App.xaml:

<Application x:Class="TestWpf2.App"              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> </Application> 

App.xaml.cs:

public partial class App : Application {     protected override void OnStartup(StartupEventArgs e)     {         var parentWindow = new Window();         parentWindow.Show();          var childWindow1 = new Window { Owner = parentWindow };         childWindow1.Show();          var childWindow2 = new Window { Owner = parentWindow };         childWindow2.Show();     } } 

The application causes 3 windows to appear on screen. If you run the application and close the two child windows, the parent window is minimized to the task bar. If you comment out childWindow2.show(), run the application, and close the single child window, the parent window is not minimized to the taskbar.

I can add the following code to work around this problem:

childWindow1.Closing += delegate(object sender, CancelEventArgs ex) {     (sender as Window).Owner = null; }; 

but I don't want to use a hack like this, and I want to understand why this problem occurs.

Why does this happen?

3 Answers

Answers 1

This is a WPF undocumented feature(Bug)

This bug has been reported to Microsoft more than 7 years ago.

Modal dialog on top of non-modal window sends main window to back.

The WPF team has recently reviewed this issue and will not be addressing this issue as at this time the team is focusing on the bugs impacting the highest number of WPF developers.

Let's look at the behavior of this undocumented feature a bit.

It doesn't Minimize, just go one window behind (in debug mode, behind the visual studio window)

Steps to prove:

  • Run this application.

  • Minimize all other windows (eg: visual studio and all other windows). Keep only these three windows on the screen.

  • Close both children, parent is still in Normal State

Test this code for further proof: StateChange wouldn't fire.

        protected override void OnStartup(StartupEventArgs e)         {             var parentWindow = new Window() { Title = "Parent" };             parentWindow.StateChanged += (sender, ep)=>             {                 var state = ((Window)sender).WindowState;             };             parentWindow.Show();              var childWindow1 = new Window { Owner = parentWindow, Title = "Child1" };             childWindow1.Show();              var childWindow2 = new Window { Owner = parentWindow, Title = "Child2" };             childWindow2.Show();         } 

Being TopMost prevent this happening

If parent window is TopMost, this wouldn't happen. But this may not be an option in many cases.

parentWindow.Topmost = true; 

Workaround

Activate the parent on child2 close.

childWindow2.Closed += (a, b) => { parentWindow.Activate(); }; 

Answers 2

This is due to the fact that you can't use the parent window once the child window is shown with the Owner set. Just try to access the parent window while the child is on the screen, and it won't let you, to see what i mean.

If you don't specify Owner then this behaviour doesn't happen.

Answers 3

I never worked out what is causing this to happen! In the end, I wrote this code that is called after any child window is closed:

// App inherits from Application, and has a Window property called MainWindow // and a List<Window> property called OpenWindows. if (!App.OpenWindows.Any())     App.ParentWindow.Activate(); 

So if the last child window is closed (making App.OpenWindows.Any() false) the parent window is activated. This does not result in flicker (the main window minimizing then maximizing, for instance.)

This isn't the best solution. I will not close this question in the hope that someone can explain why WPF has this functionality!

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment