Bon sang, on dirait qu'il y a beaucoup de code ici pour ça. Stas ci-dessus avait la bonne approche pour un effort minimal. Voici mon adaptation (en utilisant MVVMLight mais devrait être reconnaissable)... Oh et le PassEventArgsToCommand="Vrai" es définitivement nécessaire comme indiqué ci-dessus.
(crédit : Laurent Bugnion http://blog.galasoft.ch/archive/2009/10/18/clean-shutdown-in-silverlight-and-wpf-applications.aspx )
... MainWindow Xaml
...
WindowStyle="ThreeDBorderWindow"
WindowStartupLocation="Manual">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Closing">
<cmd:EventToCommand Command="{Binding WindowClosingCommand}" PassEventArgsToCommand="True" />
</i:EventTrigger>
</i:Interaction.Triggers>
Dans le modèle de vue :
///<summary>
/// public RelayCommand<CancelEventArgs> WindowClosingCommand
///</summary>
public RelayCommand<CancelEventArgs> WindowClosingCommand { get; private set; }
...
...
...
// Window Closing
WindowClosingCommand = new RelayCommand<CancelEventArgs>((args) =>
{
ShutdownService.MainWindowClosing(args);
},
(args) => CanShutdown);
dans le ShutdownService
/// <summary>
/// ask the application to shutdown
/// </summary>
public static void MainWindowClosing(CancelEventArgs e)
{
e.Cancel = true; /// CANCEL THE CLOSE - let the shutdown service decide what to do with the shutdown request
RequestShutdown();
}
RequestShutdown ressemble à ce qui suit, mais en fait, c'est RequestShutdown ou son nom qui décide d'arrêter ou non l'application (qui fermera joyeusement la fenêtre de toute façon) :
...
...
...
/// <summary>
/// ask the application to shutdown
/// </summary>
public static void RequestShutdown()
{
// Unless one of the listeners aborted the shutdown, we proceed. If they abort the shutdown, they are responsible for restarting it too.
var shouldAbortShutdown = false;
Logger.InfoFormat("Application starting shutdown at {0}...", DateTime.Now);
var msg = new NotificationMessageAction<bool>(
Notifications.ConfirmShutdown,
shouldAbort => shouldAbortShutdown |= shouldAbort);
// recipients should answer either true or false with msg.execute(true) etc.
Messenger.Default.Send(msg, Notifications.ConfirmShutdown);
if (!shouldAbortShutdown)
{
// This time it is for real
Messenger.Default.Send(new NotificationMessage(Notifications.NotifyShutdown),
Notifications.NotifyShutdown);
Logger.InfoFormat("Application has shutdown at {0}", DateTime.Now);
Application.Current.Shutdown();
}
else
Logger.InfoFormat("Application shutdown aborted at {0}", DateTime.Now);
}
}
3 votes
Je suis également intéressé par une bonne réponse à cette question.
3 votes
J'ai téléchargé le code de codeplex et le déboguer a révélé : "Unable to cast object of type 'System.ComponentModel.CancelEventArgs' to type 'System.Windows.RoutedEventArgs'." Cela fonctionne bien si vous Ne le fais pas. veulent les CancelEventArgs mais cela ne répond pas à votre question...
0 votes
Je suppose que votre code ne fonctionne pas parce que le contrôle auquel vous avez attaché votre déclencheur n'a pas d'événement de fermeture. Votre contexte de données n'est pas une fenêtre... C'est probablement un modèle de données avec une grille ou autre, qui n'a pas d'événement de fermeture. La réponse de dbkk est donc la meilleure dans ce cas. Cependant, je préfère l'approche Interaction/EventTrigger lorsque l'événement est disponible.
0 votes
Le code que vous avez fonctionnera très bien sur un événement Loaded, par exemple.