You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PowerShell GUI主从复选框联动代码实现咨询

PowerShell TreeView 复选框联动实现方案

以下是实现子项勾选自动选中父项、父项勾选自动选中所有子项的完整代码,解决操作影响整个TreeView的问题:

Add-Type -AssemblyName System.Windows.Forms

# 创建主窗体
$form = New-Object System.Windows.Forms.Form
$form.Text = "TreeView 复选框联动示例"
$form.Size = New-Object System.Drawing.Size(400, 500)

# 创建TreeView并启用复选框
$treeView = New-Object System.Windows.Forms.TreeView
$treeView.Dock = [System.Windows.Forms.DockStyle]::Fill
$treeView.CheckBoxes = $true
$form.Controls.Add($treeView)

# 填充测试节点
$root1 = $treeView.Nodes.Add("根节点1")
$child1_1 = $root1.Nodes.Add("子节点1-1")
$child1_2 = $root1.Nodes.Add("子节点1-2")
$grandChild1_2_1 = $child1_2.Nodes.Add("孙节点1-2-1")

$root2 = $treeView.Nodes.Add("根节点2")
$child2_1 = $root2.Nodes.Add("子节点2-1")

# 标记是否正在更新复选状态,避免递归触发事件导致全局修改
$updatingCheck = $false

# 处理AfterCheck事件
$treeView.Add_AfterCheck({
    param($sender, $e)
    # 如果正在更新状态,直接返回,防止循环触发
    if ($updatingCheck) { return }

    $updatingCheck = $true
    try {
        $node = $e.Node
        # 情况1:勾选父节点时,递归选中所有子节点
        if ($node.Nodes.Count -gt 0) {
            foreach ($childNode in $node.Nodes) {
                $childNode.Checked = $node.Checked
                # 手动触发子节点的AfterCheck事件,处理更深层级的子节点
                $null = $childNode.RaiseEvent([System.Windows.Forms.TreeViewEventArgs]::new($childNode, [System.Windows.Forms.TreeViewAction]::Unknown))
            }
        }
        # 情况2:勾选子节点时,向上选中所有父节点
        $parentNode = $node.Parent
        while ($parentNode -ne $null) {
            $parentNode.Checked = $true
            $parentNode = $parentNode.Parent
        }
    } finally {
        $updatingCheck = $false
    }
})

# 显示窗体
$form.ShowDialog() | Out-Null

关键逻辑说明

  1. 避免递归循环:通过$updatingCheck变量标记当前是否正在更新复选状态,防止AfterCheck事件被重复触发,解决“操作影响整个TreeView”的问题。
  2. 父项联动子项:当父节点被勾选/取消时,遍历所有子节点并同步其Checked状态,同时递归触发子节点的事件,确保多层级子节点都能同步。
  3. 子项联动父项:当子节点被勾选时,向上遍历所有父节点并设置为选中状态,满足“子项勾选父项自动选中”的需求。

如果需要实现子项全部取消时父项自动取消的进阶逻辑,可以修改子项联动部分的代码:

# 进阶:子项全部取消时父项自动取消
$parentNode = $node.Parent
while ($parentNode -ne $null) {
    # 检查父节点下是否有至少一个子节点被选中
    $hasCheckedChild = $parentNode.Nodes.Cast([System.Windows.Forms.TreeNode]) | Where-Object { $_.Checked }
    $parentNode.Checked = $hasCheckedChild -ne $null
    $parentNode = $parentNode.Parent
}

内容的提问来源于stack exchange,提问作者Spellflash

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 09:23:23