Reputation: 1992
I have created a WPF application, that is designed to run in the background and uses an icon in the system tray.
To achieve this goal, I have attached the following method to the Closing event of the MainWindow otherwise it closes. Also to note in the App.xaml I have set the ShutdownMode to OnExplicitShutdown
private void Window_Closing(object sender, CancelEventArgs e)
{
e.Cancel = true;
this.Hide();
//This method simply displays a notification to the user that the app is still running in the system tray.
DisplaySysTrayNotification();
}
The problem I am facing is that on the Context Menu of the System Tray Icon I have an Exit button which calls
App.Current.Shutdown();
This causes the Closing event to fire again and display the notification, which I do not want to do. How can I prevent this event firing again?
Or is this not possible and will I have to use a boolean variable called ShuttingDown to handle it and check this variable before displaying the notification?
Upvotes: 0
Views: 778
Reputation: 408
on window closing, the app can either be actually just fine (clicking X on the window), or really force closing (from the context menu).
one way to do this is the way you're looking for, essentially "when the context menu is clicked to 'force close' the app, remove the window event handler before calling App.Current.Shutdown()".
private void Window_Closing(object sender, CancelEventArgs e)
{
e.Cancel = true;
this.Hide();
//This method simply displays a notification to the user that the app is still running in the system tray.
DisplaySysTrayNotification();
}
private void MenuItem_Click(object sender, RoutedEventArgs e)
{
MainWindow.Closing -= Window_Closing;
App.Current.Shutdown();
}
another way to do this is to track if we're force closing the app, essentially "when the context menu is clicked to 'force close' the app, set a 'force close' flag to true so that the window knows we're actually closing for real and to not do the minimizing stuff."
this means there should be a flag in scope of both the window and the context menu. this flag would be initialized as false, considering that there will only ever be 1 force close, which will be when the app ends.
i'll call the flag _IsForceClosing. it's naturally initialized to false.
bool _IsForceClosing;
private void Window_Closing(object sender, CancelEventArgs e)
{
if (_IsForceClosing)
return; //don't do the hiding stuff, we're really closing
e.Cancel = true;
this.Hide();
//This method simply displays a notification to the user that the app is still running in the system tray.
DisplaySysTrayNotification();
}
private void MenuItem_Click(object sender, RoutedEventArgs e)
{
_IsForceClosing = true;
App.Current.Shutdown();
}
Upvotes: 2