user4968912
user4968912

Reputation: 11

Closing all windows in WPF after one has been closed

Is there any way I could close all windows after the user closes one of them, and here is the important part: without using App.Current.Shutdown(), but rather by invoking close on remaining windows individually?

My idea was to just invoke close on each of the remaining windows in the Window_Closing event handler method. There's one problem, though. Suppose I have two window classes, A and B. I create one instance of A and B - a and b respectively. If I close window A, then it invokes the Window_closing event handler method and calls b.close() there. Then in the B class (A and B are window classes, they both inherit from Window) Window_closing method is invoked (because I've just called B.close()), and B::Window_closing calls a.close() and it results in exception cause I've already closed a.

What is the right way to solve this?

Upvotes: 1

Views: 1981

Answers (3)

quetzalcoatl
quetzalcoatl

Reputation: 33566

If you are interested in having a "main window" and "tool windows", so that closing the main window closes all of them and closing tool windows does, well, only just that - then in the App.xaml there's a friendly option just for that!

That's Application.ShutdownMode

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

    StartupUri="MainWindow.xaml"
    ShutdownMode="OnMainWindowClose"
    >
</Application>

Note that here, the "MainWindow" in question, is the main window the application starts with (or the one you set as main, if you played with that during the app's lifetime).

EDIT: afterthought: That will of course close all the windows, but I'm not actually sure if it calls normal "Close", or just shutsdown the whole application. Sorry, you'd need to check it for yourself. If you're interested in my opinion, that's the way you should/could do that easily, and if you really-really-need to shutdown the app by "Close()"ing every window, then I sense you're doing something wrong here, as if I remember correctly, "Window.Close()" may be cancelled.

EDIT2: yup, Window.Close() can be cancelled. Please see this article:

Closing a window causes the Closing event to be raised. If the Closing event isn't canceled, the following occurs: (...)

So looping over the window collection and calling 'Close' doesn't really guarantee that the windows will really be closed and the app may still be left running afterwards.

Upvotes: 3

Vimal CK
Vimal CK

Reputation: 3563

Handle Window.Closedevent instead of Window.Closing which would be closing all the opened windows other than MainWindow. I am not calling Close method for MainWindow because this is the main thread which will cause application terminating.

private void Window_Closed(object sender, EventArgs e)
{
    var windows = Application.Current.Windows;
    foreach (var item in windows)
    {
       if ((item as Window).Title.ToLower() == "mainwindow") continue;
       (item as Window).Close();
    }
}

Upvotes: 0

Jcl
Jcl

Reputation: 28272

Something like this:

private static bool WindowsClosing;
public static void CloseAllWindows()
{
   if(WindowsClosing) return;
   WindowsClosing = true;
   var windows = Application.Current.Windows;
   foreach (var wnd in windows.OfType<Window>())
   {
     wnd.Close();
   }
}

And call that method from your Window_Closing (or rather Window_Closed if you don't need to cancel) events

Upvotes: 0

Related Questions