У меня точно такая же проблема, и вы правы, полагая, что MessageBox все испортил. Если честно, у меня были другие проблемы с MessageBox при работе с Windows Forms до перехода на WPF. Может быть, это просто какая-то столетняя ошибка, которая стала функцией (как это часто бывает с Microsoft)?
В любом случае, единственное решение, которое я могу вам предложить, - это то, которое сработало для меня. У меня были проблемы с получением аналогичной ситуации для работы со ListBox - если были изменения в данных в форме, когда изменился выбор ListBox (либо нажав на новый элемент, либо используя клавиши «Вверх» или «Вниз»), Я предложил пользователю выбрать в MessageBox сохранение, удаление или отмена.
Естественно, использование прямого подхода к обработке событий ListBox MouseDown или PreviewMouseDown не работало хорошо с MessageBox. Вот что сработало.
У меня есть шаблон данных для отображения элементов в моем ListBox (я почти ожидаю, что у вас будет то же самое):
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=NAME}" KeyDown="checkForChanges" MouseDown="checkForChanges"/>
</DataTemplate>
</ListBox.ItemTemplate>
Обратите внимание, как я переместил обработчики событий KeyDown и MouseDown в элемент управления TextBlock . Я сохранил тот же код:
// 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();
}
Как примечание: странно, что Binding всегда помечает мои DataRows как измененные, когда изменяется выбранный элемент в ListBox, у которого ItemsSource привязан к DataTable, (я не знаю, используете ли вы DataTables / Sets) , Чтобы бороться с этим, я отбрасываю любые необработанные изменения, когда выбор уже был изменен (потому что я обрабатываю все, что необходимо в событии MouseDown, которое происходит до этого):
<ListBox IsSynchronizedWithCurrentItem="True" [...] SelectionChanged="clearChanges"> ... </ListBox>
И код для обработчика:
private void clearChanges(object sender, SelectionChangedEventArgs e) {
Data.cancelChanges();
}