5

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

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

提前致谢!

4

2 回答 2

3

消息框的焦点更改取消了鼠标按下事件,因此它是否被处理都没有关系。由于您在显示消息框之前就知道用户试图选择哪个项目,因此如果用户按“是”,只需以编程方式选择该项目。

于 2010-12-29T18:27:19.730 回答
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,但应该是一样的。如果所选项目有未保存的更改,我使用此代码提示用户。如果用户对“继续而不保存?”回答“是”。代码继续新的选择。否则,我让消息框阻止 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
于 2012-01-30T16:48:22.927 回答