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;
逻辑说明
- 仅从传入节点的第一个直接子节点开始遍历,不处理传入节点本身(若需要处理传入节点,可自行添加
Node.Checked := Check;语句) - 对每个子节点,先设置其勾选状态,再递归处理它的所有后代节点
- 通过
GetNextSibling仅遍历当前节点的同级子节点,不会触及起始节点的兄弟节点,确保操作范围严格限定在目标节点的子树内
内容的提问来源于stack exchange,提问作者Bart Kindt
相关产品推荐
相关产品推荐

