Expand/Collapse TreeView Nodes on Ctrl+LeftMouse in WPF

Vidar 21 Reputation points
2021-03-12T13:57:22.267+00:00

I want to collapse or expand all TreeView nodes under parent node if user holds down Left Control key and presses left mouse button on expansion arrow of tree view.

How do you do this in WPF? It's not as obvious as it was in WinForms.

Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,774 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. gekka 9,181 Reputation points MVP
    2021-03-13T05:25:13.517+00:00
    <TreeView PreviewMouseLeftButtonDown="TreeView_PreviewMouseLeftButtonDown">
    
        <TreeViewItem Header="A" >
            <TreeViewItem Header="A-1" />
            <TreeViewItem Header="A-2" >
                <TreeViewItem Header="A-2-a" />
                <TreeViewItem Header="A-2-b" />
                <TreeViewItem Header="A-2-c" />
            </TreeViewItem>
            <TreeViewItem Header="A-3" />
        </TreeViewItem>
        <TreeViewItem Header="B" >
            <TreeViewItem Header="B-1" />
        </TreeViewItem>
        <TreeViewItem Header="C">
            <TreeViewItem Header="C-1" >
                <TreeViewItem Header="C-1-a" />
                <TreeViewItem Header="C-1-b" />
            </TreeViewItem>
        </TreeViewItem>
    </TreeView>
    

    怀

    private void TreeView_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        System.Diagnostics.Debug.WriteLine("PreviewMouseLeftDown");
    
        if ((Keyboard.Modifiers & ModifierKeys.Control) != ModifierKeys.Control)
        {
            System.Diagnostics.Debug.WriteLine("Not ControlKey Press");
            return;
        }
    
        var keystate = Keyboard.GetKeyStates(Key.LeftCtrl);
        if (keystate == KeyStates.None)
        {
            System.Diagnostics.Debug.WriteLine("Not Left-ControlKey Press");
            return;
        }
    
        TreeView tv = (TreeView)sender;
        TreeViewItem tvi = null;
        ToggleButton toggle = null;
        DependencyObject d = e.OriginalSource as DependencyObject;
        while (d != null)
        {
            if (d == sender)
            {
                System.Diagnostics.Debug.WriteLine("Not Found");
                return;
            }
            if (d is ToggleButton)
            {
                toggle = (ToggleButton)d;
            }
            if (d is TreeViewItem)
            {
                tvi = (TreeViewItem)d;
                break;
            }
    
            d = VisualTreeHelper.GetParent(d);
        }
    
    
        if (tvi == null || toggle == null || toggle.TemplatedParent != tvi)
        {
            System.Diagnostics.Debug.WriteLine("Not Found Toggle");
            return;
        }
    
        if (tvi.IsExpanded)
        {
            System.Diagnostics.Debug.WriteLine("Is Expanded");
            tvi.IsExpanded = false;
        }
        else
        {
            System.Diagnostics.Debug.WriteLine("Is Not Expanded");
            Dispatcher.BeginInvoke(new Action(() =>
            {
                System.Diagnostics.Debug.WriteLine("BeginInvoke");
                tvi.ExpandSubtree();
            }), System.Windows.Threading.DispatcherPriority.Loaded);
        }
        e.Handled = true;
    }
    
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.