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

Delphi:如何为已创建的TreeNode添加自定义记录

给TreeView节点添加自定义记录数据的几种方法

完全可以实现!在Delphi的TreeView控件里,最常用的方式就是利用TTreeNode的Data属性来存储自定义数据——它本质是一个指针,能指向你定义的任何记录或对象。下面给你具体的实现步骤和代码示例:

方法一:使用自定义记录 + Data属性(最直接轻量)

首先定义你需要的记录结构,比如包含节点的ID、描述等字段:

type
  // 自定义节点数据记录,可根据需求添加字段
  TNodeData = record
    NodeID: Integer;
    NodeDesc: string;
    CreateTime: TDateTime;
  end;
  // 定义记录指针,方便赋值给Data属性
  PNodeData = ^TNodeData;

添加节点时绑定数据

创建节点前,先给记录分配内存、赋值,再把指针绑定到节点的Data属性上:

var
  NewTreeNode: TTreeNode;
  NodeDataPtr: PNodeData;
begin
  // 为记录分配内存
  New(NodeDataPtr);
  // 给记录字段赋值
  NodeDataPtr.NodeID := 1001;
  NodeDataPtr.NodeDesc := '这是abc节点的专属数据';
  NodeDataPtr.CreateTime := Now;
  
  // 创建节点并绑定数据
  NewTreeNode := TreeView1.Items.Add(nil, 'abc');
  NewTreeNode.Data := NodeDataPtr;
end;

读取节点数据

需要获取节点数据时,把Data属性转换为你的记录指针类型即可:

var
  SelectedData: PNodeData;
begin
  // 先判断节点和数据是否存在,避免空指针错误
  if Assigned(TreeView1.Selected) and Assigned(TreeView1.Selected.Data) then
  begin
    SelectedData := PNodeData(TreeView1.Selected.Data);
    // 使用记录里的字段
    ShowMessage(Format('节点ID:%d'#13#10'描述:%s'#13#10'创建时间:%s', 
      [SelectedData.NodeID, SelectedData.NodeDesc, DateTimeToStr(SelectedData.CreateTime)]));
  end;
end;

关键:释放内存避免泄漏

因为我们手动用New分配了内存,所以在TreeView销毁或者删除节点时,一定要记得释放对应的内存:

// 在TreeView销毁事件中释放所有节点的数据内存
procedure TForm1.TreeView1Destroy(Sender: TObject);
var
  I: Integer;
  DataPtr: PNodeData;
begin
  for I := 0 to TreeView1.Items.Count - 1 do
  begin
    if Assigned(TreeView1.Items[I].Data) then
    begin
      DataPtr := PNodeData(TreeView1.Items[I].Data);
      Dispose(DataPtr); // 释放内存
    end;
  end;
end;

方法二:使用TObject子类(适合复杂场景)

如果需要更灵活的操作(比如给数据添加成员方法),可以定义一个继承自TObject的类,把对象赋值给Data属性:

type
  TNodeObject = class(TObject)
  public
    NodeID: Integer;
    NodeDesc: string;
    constructor Create(AID: Integer; ADesc: string);
    function GetFullInfo: string; // 自定义方法
  end;

constructor TNodeObject.Create(AID: Integer; ADesc: string);
begin
  inherited Create;
  NodeID := AID;
  NodeDesc := ADesc;
end;

function TNodeObject.GetFullInfo: string;
begin
  Result := Format('ID:%d,描述:%s', [NodeID, NodeDesc]);
end;

添加节点时:

var
  NewNode: TTreeNode;
begin
  NewNode := TreeView1.Items.Add(nil, 'abc');
  NewNode.Data := TNodeObject.Create(1001, 'abc节点的对象数据');
end;

读取时:

var
  NodeObj: TNodeObject;
begin
  if Assigned(TreeView1.Selected) and Assigned(TreeView1.Selected.Data) then
  begin
    NodeObj := TNodeObject(TreeView1.Selected.Data);
    ShowMessage(NodeObj.GetFullInfo);
  end;
end;

销毁时释放对象:

procedure TForm1.TreeView1Destroy(Sender: TObject);
var
  I: Integer;
begin
  for I := 0 to TreeView1.Items.Count - 1 do
  begin
    if Assigned(TreeView1.Items[I].Data) then
    begin
      TObject(TreeView1.Items[I].Data).Free;
    end;
  end;
end;

两种方法都能完美解决你的需求,推荐第一种自定义记录的方式,它更轻量,适合存储简单的结构化数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:15:53