Reputation: 11
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
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 theClosing
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
Reputation: 3563
Handle Window.Closed
event 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
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