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.
Here's something that seems to work for me:
<TreeView TreeViewItem.Collapsed="TreeViewItem_Collapsed" TreeViewItem.Expanded="TreeViewItem_Expanded"/>
(The above is omitting things like ItemsSource
and ItemTemplate
for brevity)
Private Sub TreeViewItem_Expanded(sender As Object, e As RoutedEventArgs)
If Keyboard.IsKeyDown(Key.LeftCtrl) Then DirectCast(e.OriginalSource, TreeViewItem).ExpandSubtree()
End Sub
Private Sub TreeViewItem_Collapsed(sender As Object, e As RoutedEventArgs)
If Keyboard.IsKeyDown(Key.LeftCtrl) Then CollapseSubtree(e.OriginalSource)
End Sub
Private Sub CollapseSubtree(Item As TreeViewItem)
Item.IsExpanded = False
For Each Child In Item.ItemContainerGenerator.Items
CollapseSubtree(Item.ItemContainerGenerator.ContainerFromItem(Child))
Next
End Sub
Since TreeViewItem.Expanded
and TreeViewItem.Collapsed
are both routed events, we can handle them at the TreeView
level as they "bubble" up. All items in the TreeView
will trigger either TreeViewItem_Collapsed
or TreeViewItem_Expanded
when they close or open, respectively.
In my quick tests, e.OriginalSource
always referred to the TreeViewItem
that was expanded/collapsed, but some more rigorous testing might be in order.
In the event handlers, we use Keyboard.IsKeyDown
to determine whether the left control key is currently being pressed. If so, we take the appropriate action.
For expansion, TreeViewItem
already has a convenient ExpandSubtree
method, so we can just use that.
For whatever reason, there is no matching CollapseSubtree
built in, so I made my own. At its heart, it's a simple recursive method that closes the node you give it and then runs itself again for all child nodes. The trick is in getting the child TreeViewItem
s (containers), instead of the data objects they are representing. To do this, I make use of the ItemContainerGenerator
, which is the class that each TreeViewItem
uses to create its children.