在第一次单击后再次选择WPF TreeviewITem

时间:2010-06-07 07:13:19

标签: asp.net .net wpf

我有一个包含2个数据级别的TreeView WPF 我已从TreeViewItemTemplate中删除了ToogleButton。现在,我想通过单击鼠标来展开/折叠组(不是双击作为默认行为)。
我试过这样的方式:

Private Sub tvArt_SelectedItemChanged(ByVal sender As System.Object, _
    ByVal e As RoutedPropertyChangedEventArgs(Of System.Object)) Handles tvArt.SelectedItemChanged

    If e.NewValue Is Nothing = False Then
        Dim ri As P_RicambiItem = TryCast(e.NewValue, P_RicambiItem)
        If ri Is Nothing = False Then
            If ri.isExpanded Then
                ri.isExpanded = False
            Else
                ri.isExpanded = True
            End If
            ri.isSelected = False
        End If
    End If
End Sub

在集合数据源中使用我的属性isExpandedisSelected

但它只能工作一半:在第一次点击之后,事实上,我无法再次点击同一项目,因为即使我取消选择它,事件处理程序“记住”它是最后选择的项目,它不会捕获事件SelectedItemChanged

我该怎么办?

2 个答案:

答案 0 :(得分:2)

最简单的方法可能是在TreeView上处理PreviewMouseDown事件,并确定鼠标何时单击父TreeViewItems:

XAML:

<TreeView Name="treeView1" TreeView.PreviewMouseDown="OnTreeViewPreviewMouseDown" />

代码隐藏:

private void OnTreeViewPreviewMouseDown( object sender, MouseButtonEventArgs e )
{
    TreeViewItem tvi = GetTreeViewItemClicked( (FrameworkElement) e.OriginalSource, treeView1 );
    if ( null == tvi ) return;
    tvi.IsExpanded = !tvi.IsExpanded;
}

private static TreeViewItem GetTreeViewItemClicked( UIElement sender, UIElement treeView )
{
    Point p = sender.TranslatePoint( new Point( 0, 0 ), treeView );
    var obj = treeView.InputHitTest( p ) as DependencyObject;
    while ( obj != null && !( obj is TreeViewItem ) )
    {
        obj = VisualTreeHelper.GetParent( obj );
    }
    return obj as TreeViewItem;
}

答案 1 :(得分:1)

非常感谢!它工作得很好,如果有人感兴趣,这是我的Vb版本:

Private Sub tvArt_PreviewMouseDown(ByVal sender As Object, ByVal e As MouseButtonEventArgs) Handles tvArt.PreviewMouseDown
    Dim tvi As TreeViewItem = GetTreeViewItemClicked(e.OriginalSource, Me.tvArt)
    If tvi Is Nothing = False Then
        If tvi.HasItems Then
            tvi.isExpanded = Not tvi.isExpanded
        End If
    End If
End Sub

Private Function GetTreeViewItemClicked(ByVal sender As UIElement, ByVal _treeView As UIElement) As TreeViewItem
    Dim p As Point = sender.TranslatePoint(New Point(0, 0), _treeView)
    Dim obj As DependencyObject = DirectCast(_treeView.InputHitTest(p), DependencyObject)
    While obj Is Nothing = False AndAlso TypeOf obj Is TreeViewItem = False
        obj = VisualTreeHelper.GetParent(obj)
    End While
    Return DirectCast(obj, TreeViewItem)
End Function