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

Delphi 11:如何仅勾选/取消勾选指定TTreeNode的子节点?

仅勾选指定TTreeNode的子节点(不影响同级节点)的Delphi实现

环境:Windows 10、Delphi 11

需求:仅为单个带复选框的TTreeNode的子节点设置.Checked属性,不影响该节点的同级节点。但现有代码会选中起始节点的所有同级节点,调用Node.GetNextChild()和Node.GetNextSibling()效果一致,无法达成需求。

现有代码:

procedure TMapIntForm.CheckAllNodes(Node: TTreeNode; Check: Boolean);
var
  AParent: TTreeNode;
begin
  AParent := Node;
  while (Node <> nil) do
  begin
    Node.Checked := Check;
    CheckAllNodes(Node.GetFirstChild(), Check);
    if Node <> TreeView.Selected then
      Node := Node.GetNextChild(Node) // .GetNextSibling()?
    else Node := nil;
  end;
end;

问题分析

原代码逻辑错误:循环中错误地将传入的起始节点纳入遍历范围,并且通过GetNextChild/GetNextSibling去遍历同级节点,导致操作扩散到起始节点的兄弟节点上。

修正后的代码

procedure TMapIntForm.CheckAllNodes(Node: TTreeNode; Check: Boolean);
var
  ChildNode: TTreeNode;
begin
  // 遍历当前节点的所有直接子节点
  ChildNode := Node.GetFirstChild;
  while ChildNode <> nil do
  begin
    // 设置当前子节点的勾选状态
    ChildNode.Checked := Check;
    // 递归处理该子节点的所有后代节点
    CheckAllNodes(ChildNode, Check);
    // 切换到下一个同级子节点
    ChildNode := ChildNode.GetNextSibling;
  end;
end;

逻辑说明

  1. 仅从传入节点的第一个直接子节点开始遍历,不处理传入节点本身(若需要处理传入节点,可自行添加Node.Checked := Check;语句)
  2. 对每个子节点,先设置其勾选状态,再递归处理它的所有后代节点
  3. 通过GetNextSibling仅遍历当前节点的同级子节点,不会触及起始节点的兄弟节点,确保操作范围严格限定在目标节点的子树内

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 20:47:02