当MessageBox出现时,Wpf停止路由事件?

时间:2010-12-29 17:50:08

标签: wpf routedevents

我在TreeView上发生了PreviewMouseDown事件,以确定用户是否可以根据某些逻辑选择其他项目。 如果当前项目数据发生更改,将显示MessageBox,询问用户是否要放弃更改。如果用户按YES,我设置e.Handled = false;以启用新选择。如果用户按NO,我设置e.Handled = true;取消新选择。

问题在于,虽然我设置了e.Handled = false,但事件停止并且TreeView上没有选择事件。有人有解决方案吗?

提前致谢!

2 个答案:

答案 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