现有数据结构如下:
ParentID ID Text imgIndex
程序代码如下
unit Unit1;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, DB, ADODB, ComCtrls, StdCtrls, Buttons;type
  PNodeRec=^TNodeRec;
  TNodeRec=Record
  name:String;
  ID:integer;
  ParentID:integer;
  end;
  TForm1 = class(TForm)
    TV: TTreeView;
    Query1: TADOQuery;
    Query2: TADOQuery;
    Button1: TButton;
    procedure LoadRootNode();
    procedure loadChilds (pID:integer;pNode:TTreeNode);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;var
  Form1: TForm1;implementation{$R *.dfm}procedure TForm1.loadRootNode() ;
var pID:integer; aNode: TTreeNode;Item : PNodeRec;
begin
Query1.close; Query1.SQL.clear;
Query1.SQL.add('select * from List where parentID=0');
Query1.open;
while not Query1.eof do
begin
Item:=New(PnodeRec);
pID:=Query1.fieldByName('id').asInteger;
item.Name :=Query1.fieldByName('Text').AsString ;
item.ID :=Query1.fieldByName('ID').AsInteger ;//(1)加载一个根节点
aNode:=TV.Items.AddObject(nil, Item^.Name,Item);//(2)加载此根节点下的所有子节点loadChilds(pID,aNode);Query1.next;end;
end;
procedure TForm1.loadChilds(pID:integer;pNode:TTreeNode);var cpID:integer; aNode: TTreeNode;Item : PNodeRec;
 i:integer;
begin//(1)加载子节点Query2.close; Query2.SQL.clear;Query2.SQL.add('select * from List where parentID='+intToStr(pID));Query2.open;while not Query2.eof dobegin//载入子节点item:=new(PNoderec);
cpID:=Query2.fieldByName('id').asInteger;
item.Name :=Query2.fieldByName('Text').AsString ;
item.ID :=Query2.fieldByName('ID').AsInteger ;
item.ParentID :=Query2.fieldByName('ParentID').AsInteger ;anode:=TV.Items.AddChildobject(pNode,Item^.Name,item);loadChilds(cpID,aNode);//此处使用递归来实现添加字节点.但是此处出错.不知道为什么
Query2.next;end;//(2)递归载入子节点的子节点
{for i:=0 to pNode.Count -1 dobeginform1.loadChilds (PNodeRec(pNode.Item[i].data)^.parentID,pNode.item[i]);
// i:=i+1;
end;}end;
procedure TForm1.Button1Click(Sender: TObject);
begin
  form1.loadRootNode ;
end;end.却不能正确的读取数据库数据的记录结构,请各位大虾指教,100分送上,因为我必须根据树节点的ID号码来表示树节点,因为树节点的文本有重复的,

解决方案 »

  1.   

    //一个比较完整的实现,最大的缺点在于速度较慢,因为每次都要找是否有子节点;
    //可能的话这个做为一个字段,以此做判断就好多了。unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
      Db, ADODB, ComCtrls, StdCtrls;type
      TForm1 = class(TForm)
        Query: TADOQuery;
        TreeView1: TTreeView;
        Button1: TButton;
        ADOConnection1: TADOConnection;
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
         procedure loadTreeFromDB(treNodes:TTreeNodes;node:TTreeNode;id:Longint);
      end;  TrecInfo= record
        id:Longint;
        customer:string;
        end;var
      Form1: TForm1;implementation{$R *.DFM}procedure Tform1.loadTreeFromDB(treNodes:TTreeNodes;node:TTreeNode;id:Longint);
    var
      nodeW:TTreeNode;
      recInfo:^TrecInfo;
      rs:_recordset;
    begin// if cust_parentid=0 then is root  query.active:=false;
      Query.sql.clear;
      query.sql.add('select * from customer where cust_parentid='+inttostr(id));
      query.active:=True;  if query.RecordCount>0 then
      begin
        rs:=query.Recordset.Clone(3);
        rs.MoveFirst;
        while not rs.EOF do
          begin
            new(recInfo);
            recInfo^.id:=rs.Fields['id'].Value;
            recInfo^.customer:=rs.Fields['cust_name'].value;
            nodew:=treNodes.AddChildObject(node,recInfo^.customer,recInfo);
            loadTreeFromDB(treNodes,nodew,recInfo^.id);
            rs.MoveNext;
          end;
        rs.Close;
      end;
    end;procedure TForm1.Button1Click(Sender: TObject);
    begin
      treeview1.Items.BeginUpdate;
      loadTreeFromDB(treeview1.Items,nil,0);
      treeview1.Items.EndUpdate;
    end;end.
      

  2.   

    我用的方法是把数据库的内容添加到一个列表(TLIST)中,然后根据这个列表生成TreeVIew
      

  3.   

    loadChilds(cpID,aNode);//此处使用递归来实现添加字节点.但是此处出错.不知道为什么
    在你调用此处递归并返回上级过程的时候,Query2已经被递归的LoadChilds Close掉了,SQL语句也换了,你如何再Query2.NEXT?就出错。
    Query2.close;
    Query2.next;
      

  4.   

    表结构:
    iden iID, NodeName, iParentID
    1    10000   商品        0
    2    11000   家电类      10000
    3    11001   电视机类    11000
    ...............................
    等。
    type
      PMenuNode=^TMenuNode;
      TMenuNode=record
         NodeID:integer;        
         NodeName:string; 
         ParentID:integer;        
       end;procedure TForm1.InitTree;
    var
      i:integer;
      ParentNode:TTreeNode;
    begin
      query.SQL.Text := 'Select iID, NodeName, ParentID from yourtable'
      query.Open;
      
      TreeView1.BeginUpdate;
      FillTree(nil, 0);
      i:= 0;
      while i < TreeView1.Items.Count do
      begin
        ParentNode := TreeView1.Items[i];
        FillTree(ParentNode, pMenuNode(ParentNode.Data)^.NodeID);
        i := i+1;
      end;
      TreeView.Items.EndUpdate;  query.close;
      query.Filtered := false;
    endprocedure TForm1.FillTree(ParentNode: TTreeNode;
       const ParentID: integer);
    var
      pNode: PMenuNode;
      CurNode: TTreeNode;
    begin  query.Filter := 'iParentID=' + IntToStr(ParentID);
      query.Filtered:=true;
      query.First;  while not query.Eof  do
      begin
        new(pNode);
        pNode^.NodeID := query.FieldByName('iID').AsInteger;
        pNode^.NodeName := trim(Query.FieldByName('NodeName').AsString);
        pNode^.ParentID := query.FieldByName('iParentID').AsInteger;    if ParentNode=nil   then
        begin
          CurNode := TreeView1.Items.AddObject(nil,
                       pNode^.NodeName, pNode);
          CurNode.ImageIndex := 2;
          CurNode.SelectedIndex := 0;    end
        else begin
          CurNode := TreeView1.Items.AddChildObject(ParentNode,
                       pNode^.NodeName, pNode);
          CurNode.ImageIndex := 1;
          CurNode.SelectedIndex := 1;
         
          Query.Next;
      end;
    end;基本如上,根据以前项目里的一段代码改的,没有调试,你自己在改改吧!