J'ai exactement le même problème et vous avez raison de penser que MessageBox est en train de tout bousiller. Pour être honnête, j'ai eu d'autres problèmes avec MessageBox tout en travaillant avec Windows Forms avant de passer à WPF. Peut-être que c'est juste un bug centenaire qui est devenu une fonctionnalité (comme souvent avec Microsoft)?
Dans tous les cas, la seule solution que je peux vous offrir est celle qui a fonctionné pour moi. J'avais des problèmes avec une situation similaire à travailler avec un ListBox - s'il y avait des changements aux données dans le formulaire, quand la sélection de la ListBox a changé (soit en cliquant sur nouvel élément ou en utilisant les clés "Up" ou "Down") J'ai offert à l'utilisateur un choix dans le MessageBox, qu'il s'agisse de sauvegarder, de rejeter ou d'annuler.
L'utilisation directe de l'approche directe de gestion des événements MouseDown ou PreviewMouseDown de ListBox ne fonctionnait pas correctement avec un MessageBox. Voici ce qui a fonctionné.
J'ai un modèle de données pour afficher les éléments dans mon ListBox (je suis presque vous attend d'avoir la même):
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=NAME}" KeyDown="checkForChanges" MouseDown="checkForChanges"/>
</DataTemplate>
</ListBox.ItemTemplate>
Notez que j'ai déplacé les gestionnaires d'événements KeyDown et MouseDown au Contrôle TextBlock à la place. J'ai gardé le même code-behind:
// The KeyDown handler
private void checkForChanges(object sender, KeyEventArgs e) {
e.Handled = checkForChanges();
}
// Method that checks if there are changes to be saved or discard or cancel
private bool checkForChanges() {
if (Data.HasChanges()) {
MessageBoxResult answer = MessageBox.Show("There are unsaved changes. Would you like to save changes now?", "WARNING", MessageBoxButton.YesNoCancel, MessageBoxImage.Question);
if (answer == MessageBoxResult.Yes) {
Data.AcceptDataChanges();
} else if (answer == MessageBoxResult.Cancel) {
return true;
}
return false;
}
return false;
}
// The MouseDown handler
private void checkForChanges(object sender, MouseButtonEventArgs e) {
e.Handled = checkForChanges();
}
Comme une note de côté, il est étrange caractère contraignant marque toujours mes DataRows tel que modifié lorsque l'élément sélectionné dans la zone de liste, qui a ItemsSource lié à un DataTable, les changements (je don ne sais pas si vous utilisez DataTables/Sets). Pour combattre, j'annuler tout changement non gérées une fois que la sélection a déjà été changé (parce que je gère tout ce qui est nécessaire en cas MouseDown qui se produit avant que):
<ListBox IsSynchronizedWithCurrentItem="True" [...] SelectionChanged="clearChanges"> ... </ListBox>
Et le code-behind pour le gestionnaire:
private void clearChanges(object sender, SelectionChangedEventArgs e) {
Data.cancelChanges();
}