开发者

Making selectable again a WPF TreeviewITem after the first click

开发者 https://www.devze.com 2023-01-02 18:08 出处:网络
I have a TreeView WPF with 2 Levels of Data. I have deleted the ToogleButton from the TreeViewItemTemplate. Now I\'d like to expand / collapse the groups with a single mouse-click (not with a double c

I have a TreeView WPF with 2 Levels of Data.

I have deleted the ToogleButton from the TreeViewItemTemplate. Now I'd like to expand / collapse the groups with a single mouse-click (not with a double click as the default behaviour).

I have tried in this way:

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

Using my properties isExpanded and isSelected in the collection dat开发者_运维问答a source.

But it works only halfway: after the first click, infact, I can't click for a second time on the same item, because, even if I've deselected it, the event handler "remembers" that it was the last selected item and it doesn't capture the event SelectedItemChanged.

How can I do?


Easiest way is probably to handle the PreviewMouseDown event on the TreeView and identify when the mouse clicks the parent TreeViewItems:

XAML:

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

Code-behind:

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;
}


Thank you very much! It works very well, if someone should be interested, this is my Vb version:

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
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号