The WPF Window class has a Closing event that fires when the window is closed. This event has an argument containing a Cancel property with a false default value. Setting this property to true inhibits the closing of the window. When this happens on the application’s MainWindow, this closing cancellation behavior applies to the application as a whole.
Some time ago, our application had code put in to pop up an “Are you sure?” style dialog and set the event's property as appropriate. The problem was it worked for some pathways through the code but not others. The lot fell to me to investigate. There are four ways to close the application: the Alt-F4 key, the task bar's Close option, the Close button in the window's title bar and an Exit menu option. All the methods worked except the Exit menu.
Digging into the code, the Exit
I know this is typical behavior and it fixes my application for now, but from a design standpoint, I'm not too sure I like this. It seems like application level shutdown code in the Window is at the wrong layer. The Application class has an Exit event that's analogous to the Window's Close event however, this does not allow canceling the operation. In my opinion, the Application class should have an Exiting event with a Cancel property on the argument, similar to the Window class' Closing event.
In any case, if your application does not call the Closing event as you expect, first check to see how it's shutdown.
(25-June-2012: Minor edit for clarity.)
5 comments:
Thanks for your post it was very helpful. I was having the same problem.
Perfect. I'm not sure what resources base.exit() clears up, but it might be a good idea to add a property to your MainWindow that records !e.cancel in your MainWindow.Close event. Then, run MainWindow.Close(); if (MainWindow.ExitOK) base.Exit();
With that said, thank you so much for finding this. You probably just saved me a few hours of unpleasant debugging and cursing.
Glad to help Anonymous.
However, I'm not sure what you're referring to with the base.Exit() references.
I meant to say base.OnExit(e). Hopefully that clears things up.
In App.xaml.cs:
protected override void OnExit(ExitEventArgs e)
{
this.MainWindow.Close();
if (MainWindow.CloseOK) //my property recorded as !e.cancel)
base.OnExit(e);
}
Ah, right. I think I see the confusion. I edited the original article to clarify I changed the Exit menu's event handler and not the application's Exit event.
I could be wrong (it's been three years since I worked on this), but I don't think putting the call to the main window's Close method in the application's Exit event will keep the application from closing if the Window's Close event is cancelled. Once control gets to the Exit event, the application will be terminated. All you can do is set the exit code that's returned to the operating system.
Post a Comment