我在TreeView上发生了PreviewMouseDown
事件,以确定用户是否可以根据某些逻辑选择其他项目。
如果当前项目数据发生更改,将显示MessageBox,询问用户是否要放弃更改。如果用户按YES,我设置e.Handled = false;
以启用新选择。如果用户按NO,我设置e.Handled = true;
取消新选择。
问题在于,虽然我设置了e.Handled = false
,但事件停止并且TreeView上没有选择事件。有人有解决方案吗?
提前致谢!
答案 0 :(得分:3)
焦点更改到消息框会取消鼠标按下事件,因此无论是否处理都无关紧要。由于您在显示消息框之前知道用户尝试选择哪个项目,因此只需在用户按YES时以编程方式选择该项目。
答案 1 :(得分:1)
我意识到这是一个老问题,我想我会加上我的答案。
实际上,@ yossharel,你知道用户试图从MouseEventArgs中选择哪个项目。你需要查看e.OriginalSource(可能是一个TextBlock),这是用户点击的内容。因此,它有一个DataContext。
因此,将TreeView的SelectedItem设置为等于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