Expand/Collapse WPF 中 Ctrl+LeftMouse 上的 TreeView 节点

Expand/Collapse TreeView Nodes on Ctrl+LeftMouse in WPF

如果用户按住左 Control 键并在树视图的展开箭头上按下鼠标左键,我想折叠或展开父节点下的所有 TreeView 节点。

如何在 WPF 中执行此操作?它不像在 WinForms 中那样明显。

这似乎对我有用:

<TreeView TreeViewItem.Collapsed="TreeViewItem_Collapsed" TreeViewItem.Expanded="TreeViewItem_Expanded"/>

(为简洁起见,以上省略了 ItemsSourceItemTemplate 之类的内容)

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

说明

TreeViewItem.Expanded and TreeViewItem.Collapsed are both routed events 以来,我们可以在 TreeView 级别处理它们,因为它们“冒泡”了。 TreeView 中的所有项目将分别在关闭或打开时触发 TreeViewItem_CollapsedTreeViewItem_Expanded

在我的快速测试中,e.OriginalSource 总是指 TreeViewItem 即 expanded/collapsed,但可能需要进行一些更严格的测试。

在事件处理程序中,我们使用 Keyboard.IsKeyDown 来确定当前是否按下了左控制键。如果是这样,我们会采取适当的行动。

对于扩展,TreeViewItem已经有一个方便的ExpandSubtree方法,所以我们可以直接使用它。

出于某种原因,没有内置匹配的 CollapseSubtree,所以我自己制作了一个。它的核心是一个简单的递归方法,它关闭您给它的节点,然后为所有子节点再次运行它自己。诀窍在于获取子 TreeViewItems(容器),而不是它们所代表的数据对象。为此,我使用 ItemContainerGenerator,这是每个 TreeViewItem 用来创建其子项的 class。