2010-12-29 2 views
5

У меня есть событие PreviewMouseDown на TreeView, чтобы определить, может ли пользователь выбрать другой элемент на основе некоторой логики. Если данные текущего элемента изменены, появится MessageBox, который запрашивает у пользователя, хочет ли он отказаться от изменений. если пользователь нажмет YES, я установил e.Handled = false;, чтобы включить новый выбор. и если пользователь нажмет NO, я установил e.Handled = true;, чтобы отменить новый выбор.Событие остановки остановки Wpf при появлении MessageBox?

Проблема заключается в том, что, хотя я установил e.Handled = false, событие события и событие выбора не происходит в TreeView. У кого-то есть решение для этого?

Заранее благодарен!

ответ

3

Изменение фокуса в окне сообщения отменяет событие мыши, поэтому не имеет значения, обрабатывается оно или нет. Поскольку вы знаете, какой элемент пользователь пытался выбрать перед отображением окна сообщения, просто выберите этот пункт программно, если пользователь нажмет YES.

+0

Но я не знаю, какой элемент пользователь пытался выбрать. У меня только MouseEventArgs. Любая идея, как получить этот элемент, или я должен зарегистрироваться в SelectedItemChanged? – yossharel

+1

Используйте эту технику для получения DataContext: http://stackoverflow.com/questions/1092639/in-wpf-how-do-i-get-the-data-object-associated-to-the-tree-view-item -underne и затем использовать SelectedItems.Add() –

+0

MouseEventArgs.Source сообщает вам объект, на который был нажат. Я делал что-то подобное с TabItems (отображая диалог, когда пользователь выбрал другую вкладку), и исправить было установить myTabControl.SelectedItem = e.Source. – TarkaDaal

1

Я понимаю, что это старый вопрос, подумал я, добавлю свой ответ.

На самом деле, @yossharel, вы знаете, какой элемент пользователь пытался выбрать, из MouseEventArgs. Вам нужно посмотреть на e.OriginalSource (возможно, TextBlock), на который пользователь нажал. Таким образом, он имеет DataContext.

Итак, установите SelectedOtem TreeView равным e.OriginalSource.DataContext.

В VB, вы можете быть явным или неявным: myTreeView.SelectedItem = CType (e.OriginalSource, TextBlock) .DataContext() myTreeView.SelectedItem = e.OriginalSource.DataContext()

В C# вам нужно будет определить тип e.OriginalSource. Сделайте это, поставив точку перерыва и посмотрите, что Studio сообщает вам, что это так. В этом примере: myTreeView.SelectedItem = ((TextBlock) e.OriginalSource) .DataContext()

Вот пример из моего собственного кода. В моем случае это DataGrid вместо TreeView, но должен работать одинаково. Я использую этот код для запроса пользователю о несохраненных изменениях в выбранном элементе. Если пользователь отвечает «Да» на «Продолжить без сохранения?» код продолжает новый выбор. В противном случае я позволяю Message Box блокировать RoutedEvent, предотвращая запуск события SelectionChanged.

Private Sub dgDataGrid_PreviewMouseLeftButtonDown(sender As Object, e As System.Windows.Input.MouseButtonEventArgs) Handles dgDataGrid.PreviewMouseLeftButtonDown 
    If dgDataGrid.SelectedItem IsNot Nothing Then 
     If MyDataContext.ExternalViewModel.ItemIsModified Then 
      Dim prompt As String = String.Format("Changes have not been saved.{0}{0}Continue without saving?", vbCrLf) 
      Dim title As String = "Changes Not Saved" 
      Dim result As MsgBoxResult = MsgBox(prompt, MsgBoxStyle.Exclamation Or MsgBoxStyle.YesNo, title) 
      If result = MsgBoxResult.Yes Then 
       dgDataGrid.SelectedItem = e.OriginalSource.DataContext() 
      End If 
     End If 
    End If 
End Sub 

Private Sub dgDataGrid_SelectionChanged(sender As System.Object, e As System.Windows.Controls.SelectionChangedEventArgs) Handles dgDataGrid.SelectionChanged 
    MyDataContext.SetSearchItem(dgDataGrid.SelectedItem) 
End Sub