我查找了一些贴子,都是通过两个字段(一个自己的ID,一个是父节点的ID)来生成treeView的,我想用另一种办法,只有一个字段ID,但其值有层次关系,如下tree.db  
ID                NAME  
-----------------  
wj01000000    test01  
wj01010000    test0101  
wj01010100    test010101  
wj01010200    test010102  
wj01010300    test010103  
wj01020000    test0102  
wj01020100    test010201  
wj01020200    test010202  
wj01020300    test010203  
wj02000000    test02  
wj02010000    test0201  
 
生成的树就应如下:  
test01  
     test0101  
           test010101  
           test010102 
           test010103  
     test0102  
           test020101  
           test020102  
           test020103  
test02  
     test0201  
 
并且要求:
1,在treeView上有增、删节点的功能,并同步存储到数据库表中
2,通过指定ID,能快速定位并展开该节点。
 
请问如何实现?(初学delphi,请讲得详细点,最好有完整代码,分不够可另加到你满意为止!!)  

解决方案 »

  1.   

    我觉得可以先提出数据库里的id,然后到treeview里去查找结点,先从主结点查是否有相同等级的子串,有的话再继续到子结点查,知道合适的位置再插入。可惜现在没delphi,只能讲理论。呵呵
      

  2.   

    用dxdbtreeview控件,可以少写很多代码
      

  3.   

    我从别人那里找到
    一个递归建树的方法,任意值无需有规律,与大家分享
    procedure AddClass(AId: string; FatherNode: TTreeNode; temp_treeview: Ttreeview);
    var
      QryTmp: TADOQuery;
      myNode: TTreeNode;
      myLabel: TLabel;
    begin
      QryTmp := TADOQuery.Create(application);
      qrytmp.connection := form1.ADOConnection1;
      QryTmp.SQL.Add('select * from pro_bom');
      QryTmp.SQL.Add('where cp_peij_no=:AId');
      qrytmp.Parameters.ParamByName('aid').value := aid;
      QryTmp.Open;
      while not QryTmp.Eof do
      begin
        myNode := temp_Treeview.Items.AddChild(FatherNode, QryTmp.fieldbyname('wl_peij_no').AsString);
             //创建标签,caption存放各分支的AutoId表识
        myLabel := TLabel.Create(application);
        myLabel.Visible := false;
        myLabel.Caption := QryTmp.fieldbyname('wl_peij_no').AsString;
        myNode.Data := myLabel;
        AddClass(QryTmp.fieldbyname('wl_peij_no').Asstring, myNode, temp_treeview); //递归用过程
        QryTmp.Next;
      end;
      QryTmp.Free;
    end;
    procedure TForm1.Button2Click(Sender: TObject);
    begin
        AddClass('all',nil,bosstreeview1);
    end;
      

  4.   

    可以这样做:
    unit main;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, ExtCtrls, ImgList, ComCtrls, Grids, DBGrids, DB, ADODB, StdCtrls,
      DBCtrls;type
        TfrmMain = class(TForm);
        imgIcon: TImageList;
        tblCode: TADOQuery;
        tvwCode: TTreeView;
        ADOQuery1: TADOQuery;
        ADOTable1: TADOTable;
        DBGrid1: TDBGrid;
        DataSource1: TDataSource;
        procedure FormCreate(Sender: TObject);
      private
        { Private declarations }
        function LoadCode(crTbl:TADOQuery):Integer;
        function GetLevel(sFormat,sCode:String):Integer;
      public
        { Public declarations }
      end;var
      frmMain: TfrmMain;
      const
      SCodeFormat = '322222';   
      SFirstNodeTxt   = '贵州师大学科';implementation{$R *.dfm}function TfrmMain.LoadCode(crTbl:TADOQuery):Integer;
    var NowID,sName,ShowTxt:String;
    i,Level:Integer;
    MyNode:array[0..6]of TTreeNode;
    beginScreen.Cursor:=crHourGlass;
    Level:=0;With crTbl do
    begin
    try
    if not Active then Open;
    First;
    tvwCode.Items.Clear;
    MyNode[Level]:=tvwCode.Items.Add
    (tvwCode.TopItem,SFirstNodeTxt);
    MyNode[Level].ImageIndex:=0;
    MyNode[Level].SelectedIndex:=0;While Not Eof do
    begin
    NowID:=Trim(FieldByName('aCode').AsString);
    ShowTxt:=NowID+'  '+FieldByName('aName').AsString;Level:=GetLevel(SCodeFormat,NowID);
    begin    Edit1.text:=inttostr(Level);
       MyNode[Level]:=tvwCode.Items.AddChild(MyNode[Level-1],ShowTxt);
       
       MyNode[Level].ImageIndex:=1;
       MyNode[Level].SelectedIndex:=2;
             
    end;
    Next;
    end;
    finally
    Close;
    end;
    end;MyNode[0].Expand(False);
    Screen.Cursor:=crDefault;
    end;
    function TfrmMain.GetLevel
    (sFormat,sCode:String):Integer;
    var i,Level,iLen:Integer;
    begin
    Level:=-1;
    iLen:=0;
    if (sFormat <> '')and(sCode <> '')then
    for i:=1 to Length(sFormat) do
    begin
    iLen:=iLen+StrToInt(sFormat[i]);
    if Length(sCode)=iLen then
    begin
       Level:=i;
       Break;
    end;
    end;
    Result:=Level;
    end;procedure TfrmMain.FormCreate(Sender: TObject);
    begin
    with tblCode do
    begin
    ConnectionString:='Provider=SQLOLEDB.1;Password=lj721891;Persist Security Info=True;User ID=sa;Initial Catalog=study;Data Source=LEGEND-3LI8VJ5O\WWW' ;
    SQL.Add('select *from tree_data order by aCode')  ;
    Active:=true;
    end;
    LoadCode(tblCode);
    end;
    end.
      

  5.   

    以上我改写人家的代码,改用ADO存储访问数据库
      

  6.   

    由数据库表生成treeview, 已参考例子成功(我与 phy2002(大鸟) 参考的应是同一个例子),现在还剩两个小问题:
    1,在treeView上有增、删节点的功能,并同步存储到数据库表中
    2,通过指定ID,能快速定位并展开该节点。谢谢以上各位,继续等待ing.
      

  7.   

    我自己又解决一个问题:
       2,通过指定ID,能快速定位并展开该节点。还差一个问题,请指点:
       1,在treeView上有增、删节点的功能,并同步存储到数据库表中
    谢谢!!!