数据库结构如下,
type_id 节点的唯一表示 (data值)
type_name 节点名称(text值)
parent_id父节点ID
该用什么方法实现节点的添加

解决方案 »

  1.   

    var setnode: ttreenode;
    adoquery1.open ;
    while not adoquery1.eof
           begin
           SetNode := treeview1.Items.Add(nil, adoquery1.fieldbyname('data') ;
           treeview1.Items.AddChild(SetNode, adoquery1.fieldbyname('text')) ;
           adoquery1.next
           end ;
      

  2.   

    你运行这个后就明白了:
    procedure TForm1.Button2Click(Sender: TObject);
    var node,node1: TTreenode;
    begin
    Treeview1.Items.Clear ;
       node:=Treeview1.Items.Add(nil,'123');
        node1:=Treeview1.Items.AddChild(node,'345');
        Treeview1.Items.AddChild(node,'abc');
        Treeview1.Items.AddChild(node1,'09') ;
    end;
      

  3.   

    拜托, breezing(前不见gz 后不见up) ,那节点间的父子关系如何体现啊?
      

  4.   

    TviewEnterprise.Items.Clear;
        TviewEnterprise.Items.Add(nil,'浙江省');
        TNodeBoot:=TTreeNode.Create(nil);
        TNodeBoot:=TviewEnterprise.Items[0];
        AdoqrEnterprise:=TADOQuery.Create(nil);
        AdoqrEnterprise.Connection :=AdocnCar;
        AdoqrEnterprise.SQL.Text:='Select EnterpriseID,EnterpriseName from C_Enterprise Where UpCode=0 Order by ViewOrder';
        AdoqrEnterprise.Open;
        While not AdoqrEnterprise.Eof do
        begin
            TNodeSub:=TTreeNode.Create(nil);
            TNodeSub:=TviewEnterprise.Items.AddChild(TNodeBoot,AdoqrEnterprise.FieldValues['EnterpriseName'] );
            AddChildTree(TNodeSub,AdoqrEnterprise.FieldValues['EnterpriseID']);
            if TNodeSub.getFirstChild<>nil then TNodeSub.Expanded:=True;
            application.ProcessMessages;
            AdoqrEnterprise.Next;
        end;
        TViewEnterprise.Items[0].Expanded:=true;
        AdoqrEnterprise.Close;
        AdoqrEnterprise.Free;procedure TFraEnterprise.AddChildTree(TNodeBoot:TTreeNode;IntUpCode:Integer);
    var
        AdoqrChild:TADOQuery;
        TNodeSub:TTreeNode;
    begin
        Application.ProcessMessages;
        FrmProgress.ProBar.Position:=FrmProgress.ProBar.Position +10;
        if Frmprogress.ProBar.Position=200 then FrmProgress.ProBar.Position:=0;
        AdoqrChild:=TADOQuery.Create(nil);
        AdoqrChild.Connection:=AdocnCar;
        AdoqrChild.SQL.Text:='Select EnterpriseID,EnterpriseName,IsLeaf from C_Enterprise Where UpCode='+InttoStr(IntUpCode)+ ' Order by ViewOrder';
        AdoqrChild.Open;
        while not AdoqrChild.Eof do
        begin
            TNodeSub:=TTreeNode.Create(nil);
            TNodeSub:=TviewEnterprise.Items.AddChild(TNodeBoot,AdoqrChild.FieldValues['EnterpriseName']);
            if AdoqrChild.FieldValues['IsLeaf']=0 then AddChildTree(TNodeSub,AdoqrChild.FieldValues['EnterpriseID']);
            AdoqrChild.Next;
        end;
        AdoqrChild.Close;
        AdoqrChild.free;end;
    这是我的部分代码,自己参考一下吧,修行得靠自己,呵呵
      

  5.   

    unit UTreeFun;interface
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, ComCtrls, ToolWin, Grids, DBGrids, DB, ExtCtrls, ImgList, ADODB,
      StdCtrls;  //该结构保存数据的节点信息
      type
        PNodeInfor=^TNodeInfor;
        TNodeInfor=Record
           KeyId:string[10];
           FParentID:string[10];
           FName:string;
    //       IsEnd:Boolean;
    //       IsCanDel:Boolean;
      end;
      //创建TreeView
      function CreateATree(var TreeView:TTreeView;const adoData:TADOTable):boolean;
      //创建子接点
      function CreateSubNode(var Node:TTreeNode;ParentKey:String;TreeView:TTreeView;
        const adoData:TADOTable):Boolean;implementationfunction CreateATree(var TreeView:TTreeView;const adoData:TADOTable):boolean;
    var
      tmpTree:TTreeView;
      tmpItems:TTreeNodes;
      tmpNode:TTreeNode;
      tmpNodeInfor:PNodeInfor;
      tmpBookMark:String;
    begin
      Result:=False;
      tmpNode:=TTreeNode.Create(nil);
      tmpTree:=TreeView;
      tmpItems:=tmpTree.Items;
      tmpItems.Clear;{清除当前所有节点}
      if (not adoData.Active)or(adoData.RecordCount<=0) then
      begin
        Application.MessageBox('数据表中没有数据!','提示',mb_ok+mb_iconwarning);
        Exit;
      end;
      with adoData do
      begin
        First;
        New(tmpNodeInfor);
        tmpNodeInfor.KeyId:=Trim(FieldByName('己编码').AsString);
        tmpNodeInfor.FParentID:=Trim(FieldByName('父编码').AsString);
        tmpNodeInfor.FName:=Trim(FieldByName('名称').AsString);
    //    tmpNodeInfor.IsEnd:=FieldByName('FIsEnd').AsBoolean;
    //    tmpNodeInfor.IsCanDel:=FieldByName('FCanDel').AsBoolean;
        while not EOF do
        begin
          if FieldByName('己编码').AsString=FieldByName('父编码').AsString then
          begin
            tmpNode:=tmpItems.AddObject(nil,tmpNodeInfor.FName,tmpNodeInfor);
            tmpBookMark:=string(BookMark);
            if not CreateSubNode(tmpNode,tmpNodeInfor.KeyId,TreeView,adoData) then
            begin
              Exit;
            end;
            BookMark:=tmpBookMark;
            Next;
          end
          else
            Next;
        end;
      end;
      adoData.First;
      Result:=true;
    end;function CreateSubNode(var Node:TTreeNode;ParentKey:String;TreeView:TTreeView;
    const adoData:TADOTable):Boolean;
    var
      tmpTree:TTreeView;
      tmpItems:TTreeNodes;
      tmpNodeSub:TTreeNode;
      tmpNodeInfor:PNodeInfor;
      tmpBookMark:String;
      FID:string;
    begin
      Result:=False;
      tmpTree:=TreeView;
      tmpItems:=tmpTree.Items;
      FID:=ParentKey;
      tmpNodeSub:=TTreeNode.Create(nil);
      with adoData do
      begin
        First;
        while not EOF do
        begin
          New(tmpNodeInfor);
          tmpNodeInfor.KeyId:=Trim(FieldByName('己编码').AsString);
          tmpNodeInfor.FParentID:=Trim(FieldByName('父编码').AsString);
          tmpNodeInfor.FName:=Trim(FieldByName('名称').AsString);
    //      tmpNodeInfor.IsEnd:=FieldByName('FIsEnd').AsBoolean;
    //      tmpNodeInfor.IsCanDel:=FieldByName('FCanDel').AsBoolean;      if (FieldByName('父编码').AsString=FID)and
            (FieldByName('己编码').AsString<>FieldByName('父编码').AsString) then
          begin
            tmpNodeSub:=tmpTree.Items.AddChildObject(Node,tmpNodeInfor.FName,tmpNodeInfor);
            tmpBookMark:=string(BookMark);
            if not CreateSubNode(tmpNodeSub,tmpNodeInfor.KeyId,TreeView,adoData) then
              Exit;
            BookMark:=tmpBookMark;
            Next;
          end
          else
            Next;
        end;
      end;
      Result:=True;
    end;end.
      

  6.   

    你的数据表应该加一个字段priorid(父节点id)
    不然就不需要用什么递归了 直接一个循环就ok了
    看看我的递归算法吧 ^_^ 很厉害的呀 参考一下
    //介绍一下 表字段(node_id,node_name,prior_nodeid)  i全局变量
    function TForm1.shownode(Fnode: ttreenode;
      p_id: string): boolean;
    var tempnode1:ttreenode;
    s_id:string;
     begin
    //*********动态创建查询控件
       i:=i+1;
       Tadoquery.Create(Self).Name :='adotemp' + IntToStr(i);
        with Tadoquery(FindComponent('adotemp' + IntToStr(i))) do
        begin
         Connection:=adoconn;//连接
         Parent := self;
      Close;
      SQL.Clear;
      SQL.Add('select * from data_node where prior_nodeid='+p_id);
    Open;   while(not Eof) do
           begin
          s_id:=FieldByName('node_id').asstring;//得到父节点id再次递归
           tempnode1:=tv.Items.AddChild(Fnode,trim(Fields.fieldbyname('node_name').AsString));//添加节点
           shownode(tempnode1,s_id);//递归
           Next;
        end;
           end;
    end;end;
      

  7.   

    我的结构和你差不多,不过是文本文件。id           编号
    p_id     父编号
    title        标题
    jb           级别
    px    排序(保存节点在数据库中唯一编码)
    sj           是否含有数据
    fname        照片名        0##-1##eee##0##4##0
    1##0##aa##1##5##0
    2##0##bb##1##10##0
    3##0##gg##1##9##0
    4##3##新建相册##2##12##0
    5##4##aa.jpg##3##14##1
    6##3##新建相册##2##18##0
    7##6##b##3##8##1
    8##3##aa.jpg##2##15##1
    9##3##新建相册##2##17##0
    10##0##ee##1##16##0
    11##10##fm.bmp##2##20##1
    12##10##C:\i\picture\move2.bmp##2##19##1procedure Tmusic.load_list;  //从system下music.mz中得到树状列表
    var
      i,j:integer;
      p_node:Ttreenode;
      l_pid:integer;
      l_id:integer;
      l_title:string;
      l_jb:integer;
      l_sj:integer;
      jd_str:string;
      m_str:string;
      ls_px:integer;
    begin
      allow_md:=0;
      //得到结点的最大px值。
      ls_px:=0;
      //清空树
      tv_music.Items.clear;
      //打开目录表
      m_list.Lines.LoadFromFile(s_path+'\music.mz');
      if m_list.Lines.Count<1 then
        begin
          allow_md:=1;
          check_tree;
          save_list;
          m_list.Lines.LoadFromFile(s_path+'\music.mz');
          allow_md:=0;
        end;
      //清空树
      tv_music.Items.clear;
      //遍历目录表
      for i:=0 to m_list.Lines.Count-1 do
        begin
          //取值
          m_str:=m_list.Lines[i];
          //给结点结构赋值
          new(ls_rec);
          try
            begin
              ls_rec^.px:=strtoint(get_substr(m_str,DIV_STR,5));
              if ls_px<ls_rec^.px then
                ls_px:=ls_rec^.px;
            end;
          except
            ls_rec^.px:=-1;
          end;
          try
            ls_rec^.sj:=strtoint(get_substr(m_str,DIV_STR,6));
          except
            ls_rec^.sj:=1;
          end;
          l_sj:=ls_rec^.sj;
          try
            ls_rec^.fname:=get_substr(m_str,DIV_STR,7);
          except
            ls_rec^.fname:='';
          end;
          try
            l_pid:=strtoint(get_substr(m_str,DIV_STR,2));
          except
            l_pid:=-1;
          end;
          try
            l_id:=strtoint(get_substr(m_str,DIV_STR,1));
          except
            l_id:=0;
          end;
          try
            l_jb:=strtoint(get_substr(m_str,DIV_STR,4));
          except
            l_jb:=0;
          end;
          try
            l_title:=get_substr(m_str,DIV_STR,3);
          except
            l_title:='';
          end;      if l_id=0 then
            begin
              with tv_music.Items do
                begin
                  p_node:=AddObject(nil,l_title,ls_rec);
                  p_node.imageindex:=0;
                  p_node.selectedindex:=1;
                end;
            end
          else
            begin
              //增加进目录树
              jd_str:=l_title;
              //如果树为第0层
              if l_jb=0 then
                add_jd(tv_music,0,l_jb,jd_str,l_sj)
              //否则
              else
                add_child_jd(tv_music,l_pid,l_jb,jd_str,l_sj);
            end;
        end;
      if ls_px<1 then
        p_px_value:=1
      else
        p_px_value:=ls_px+1;
      allow_md:=1;
      tv_music.FullCollapse;
      tv_music.Items[0].Selected:=true;
    end;procedure Tmusic.add_jd(l_tree:TTreeview;n_id,jb:integer;jdcaption:string;zt:integer);
    var
      ls_node,P_node:TTreeNode;
    begin
      with l_tree.Items do
        begin
          ls_node:=l_tree.Items[n_id];
          p_node:=AddObject(ls_node,jdcaption,ls_rec);
          p_node.imageindex:=0;
          p_node.selectedindex:=1;
          //如果zt为1则有数据,为0则不。
          if zt=1 then
            p_node.ImageIndex:=2;
          //生成目录
          if (allow_md=1) and (zt=0) then
            mk_dir(get_dir_str(m_path,p_node));
          p_node.Selected:=true;
        end;
    end;procedure Tmusic.add_child_jd(l_tree:TTreeview;n_id,jb:integer;jdcaption:string;zt:integer);
    var
      ls_node,P_node:TTreeNode;
    begin
      with l_tree.Items do
        begin
          ls_node:=l_tree.Items[n_id];
          p_node:=AddChildObject(ls_node,jdcaption,ls_rec);
          p_node.imageindex:=0;
          p_node.selectedindex:=1;
          //如果zt为1则有数据,为0则不。
          if zt=1 then
            p_node.ImageIndex:=2;
          //生成目录
          if (allow_md=1) and (zt=0) then
            mk_dir(get_dir_str(m_path,p_node));
          p_node.Selected:=true;
        end;
    end;
      

  8.   

    http://www.nxit.net/bbs/dispbbs.asp?boardID=1&ID=1042 有源代码。几种实现的方法
    http://www.nxit.net/bbs -> delphi -> 小小,看这个//标题。图片
    http://www.nxit.net/bbs/UploadFile/200358931597578.jpg
    http://www.nxit.net/bbs/UploadFile/200358932290074.jpg
    ---------------------------------------------------
    搞什么啊!!!!!!我回复这个贴子至少有十次了,他还上不去。
      

  9.   

    正好,我也在做,大家交流一下吧(但不是递归的)而且有个限制,子节点id比父节点要长:
    只要表结构是(id,name,parent)的生成树型代码(treeview)
    定义类型:
    type          //记录字段数据
       tabledata = record
         id:string;
         name:string;
         parentid:string;
    end;
    type          //中间变量
       Nodemsg = record
         id:string;
         name :string;
    end;
    定义变量:
    Mynode:array[0..50] of Nodemsg;
    定义代码:
    var
    MyTreeNode1:TTReeNode;
    i,j,k,m:integer;
    tabledata1:tabledata;
    begin
        MyTreeNode1:=nil;
        treeview1.Items.Clear ;
        with adoquery1 do begin
          close;
          sql.Clear ;
          sql.Add('select * from jy_zongbiao');
          {sql.Add('select *');
          sql.Add('from '+BUMENBIANMA); }
          sql.Add('order by f_parent,f_id');
          active:=true;
          execsql;
        end;
          i:=0;
          k:=0;
        //end;
     {1}while not adoquery1.Eof do begin
          //先处理根结点
       {2}if i=0 then begin
            tabledata1.id := adoquery1.fieldbyname('f_id').AsString ;
            tabledata1.name := adoquery1.fieldbyname('f_name').AsString ;
            tabledata1.parentid := adoquery1.fieldbyname('f_parent').AsString ;
            //k:=adoquery1.RecordCount ;
            with TreeView1.Items do
            begin
              clear;
              MyTreeNode1:=Add(nil,tabledata1.name );
            end;
            Mynode[i].id :=tabledata1.id ;
            Mynode[i].name := tabledata1.name ;
            adoquery1.Next ;
            inc(i);
       {2}end
       {3}else begin
            //处理子节点
            tabledata1.id := adoquery1.fieldbyname('f_id').AsString ;
            tabledata1.name := adoquery1.fieldbyname('f_name').AsString ;
            tabledata1.parentid := adoquery1.fieldbyname('f_parent').AsString ;
            for j:=k to i do begin
              if Mynode[j].id =tabledata1.parentid then
              begin
                 m:=0;
                 while m<i do begin
                   if trim(Mynode[j].name)=trim(treeview1.Items[m].Text) then
                      break;
                   inc(m);
                 end;
                 MyTreeNode1:=treeview1.Items[m];
                 k:=j;
                 Mynode[i].id :=tabledata1.id ;
                 Mynode[i].name := tabledata1.name ;
                 break;
              end;
            end;
            treeview1.Items.AddChild(MyTreeNode1,tabledata1.name);
            adoquery1.Next ;
            inc(i);
       {3}end;
      {1}end;
      treeview1.FullExpand ;
    end;
      

  10.   

    其实大家的算法都差不多阿,不过我觉得写的还是有点长阿
    我这里是我自己写的
    procedure TForm1.Mydggc(Node:TTreeNode;id:integer);
    var
      i:integer;
      Text:string;
      MyBoolean_1:boolean;
    begin
      for i:=0 to Count-1 do
        begin
          if Myarray[i,2]=id then
            begin
              if MyBoolean_1=false then
                Node:=TV1.Items.AddChild(Node,Myarray[i,1])
              else
                begin
                  Node:=TV1.Items.Add(Node,Myarray[i,1]);
                  MyBoolean_1:=false;
                end;
              Mydggc(Node,Myarray[i,0]);
              MyBoolean_1:=true;
            end;
        end;
    end;
    动态数组是从数据库里面取出的数据包括(本级id,上级id以及这一级的文本)
    count是数据库的记录个数
    在调用的时候
    直接使用Mydggc(nil,0)就行了
    希望和大家能够互相探讨一下