2010-12-29 12 views
5

Ho un evento PreviewMouseDown su TreeView per determinare se l'utente può selezionare altro elemento in base a una logica. Se i dati dell'elemento corrente sono cambiati, verrà visualizzato MessageBox che chiede all'utente se desidera ignorare le modifiche. se l'utente preme SÌ, imposto e.Handled = false; per abilitare la nuova selezione. e se l'utente preme NO, imposto e.Handled = true; per annullare la nuova selezione.Wpf stop routing evento quando MessageBox appare?

Il problema è che sebbene io abbia impostato e.Handled = false, l'evento si interrompe e nessun evento di selezione si verifica su TreeView. Qualcuno ha una soluzione per questo?

Grazie in anticipo!

risposta

3

Il cambio di messa a fuoco nella finestra di messaggio annulla l'evento mouse down in modo che non importi se viene gestito o meno. Poiché tu sai quale elemento l'utente stava cercando di selezionare prima di visualizzare la finestra del messaggio, seleziona semplicemente quell'elemento a livello di codice se l'utente preme SÌ.

+0

Ma non so quale elemento l'utente stava cercando di selezionare. Ho solo MouseEventArgs. Qualche idea su come ottenere questo oggetto o dovrei registrarmi a SelectedItemChanged? – yossharel

+1

Utilizzare questa tecnica per ottenere DataContext: http://stackoverflow.com/questions/1092639/in-wpf-how-do-i-get-the-data-object-associato-per-il-tree-view-item -underneath e quindi usa SelectedItems.Add() –

+0

MouseEventArgs.Source ti dice l'oggetto su cui è stato fatto clic. Stavo facendo qualcosa di simile con TabItems (visualizzando una finestra di dialogo quando l'utente ha selezionato una scheda diversa) e la correzione era per impostare myTabControl.SelectedItem = e.Source. – TarkaDaal

1

Mi rendo conto che questa è una vecchia domanda, ma ho pensato di aggiungere la mia risposta.

In realtà, @yossharel, tu sai quale elemento l'utente stava cercando di selezionare, da MouseEventArgs. Devi guardare e.OriginalSource (probabilmente un TextBlock), che è ciò su cui l'utente ha fatto clic. Come tale, ha un DataContext.

Quindi, impostare l'oggetto SelectedView TreeView uguale a e.OriginalSource.DataContext.

In VB, si può essere esplicita o implicita: myTreeView.SelectedItem = CType (e.OriginalSource, TextBlock) .DataContext() myTreeView.SelectedItem = e.OriginalSource.DataContext()

In C#, sarà necessario determinare il tipo di e.OriginalSource. Fai questo inserendo un punto di interruzione e vedi cosa Studio ti dice che lo è. In questo esempio: myTreeView.SelectedItem = ((TextBlock) e.OriginalSource) .DataContext()

Ecco un esempio tratto dal mio codice. Nel mio caso, è un DataGrid invece di un TreeView, ma dovrebbe funzionare allo stesso modo. Io uso questo codice per richiedere all'utente se ci sono modifiche non salvate sull'elemento selezionato. Se l'utente risponde "Sì" a "Continua senza salvare?" il codice continua con la nuova selezione. Altrimenti, lascio che la Message Box blocchi RoutedEvent, impedendo l'attivazione dell'evento 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