是关于Treeview 读取节点的问题
有一存储节点信息的表
table:
typ_code(节点的代码)
typ_name(节点名称)
node (节点所属于的层数)例子:01   
Delphi
10101
Delphi数据库编程
2Delphi为父节点,Delphi数据库编程为他的子节点
其后都符合这个规律,
0101001为Delphi数据库编程的子节点假如表中有无数个记录的话,我们怎么把他们从表中读取到Treeview中呢?

解决方案 »

  1.   

    你在有treeview向数据库保存时,记住每个节点的AbsoluteIndex,
    同时如过该节点有父节点的话,保存父节点的AbsoluteIndex,
    那你再由数据库读出的时候就很简单了.
      

  2.   

    记住保存和读出都要按照AbsoluteIndex的顺序
      

  3.   

    procedure LoadTree(treeDB:TDBDataSet);//初始化树
        procedure UpdateTree(curNode:TTreenode; nodeTxt:string; state:string);//更新树
        function  GetNodeLevel(sFormat,sCode:string):integer; //获得节点层数
        function  GetNodeItem(sCode:string):integer;//获得item    { Public declarations }
      end;    const
      CTreeCodeFormat='122222';
      cTreeMaxLevel=6;
      CTreeRootTXT='所有图书';var
      tsgzlfrom: Ttsgzlfrom;
      _err:integer;
      curUser:string[10];
      mystate:string;
      gNodeId:string;
      gNodelevel:integer;
      gNode:TtreeNode;
      mynode:array[0..6] of TTreenode;
      i,Already,CurMode:integer;
      currow:integer;
      iniFile:string;
      HasSub:String;  level:Integer;
      implementationuses bgNewunit;
    {$R *.DFM}procedure TtsgzlFrom.LoadTree(treeDB:TDBDataSet);//初始化树
    var curID,nodeTxt:string;
        level,num:integer;
    begin
        //初始化变量
        Screen.Cursor:=crHourGlass;
        tree.Enabled:=True;
        tree.Items.Clear;
        level:=1 ;
        num:=1;
        tree.items.clear;
        //设置根节点
        mynode[level]:=Tree.items.add(Tree.Topitem,cTreeRootTxt);
        mynode[level].ImageIndex:=0;
        mynode[level].SelectedIndex:=1;
        //遍历数据表,利用编码字段记录排序规律,依次添加树节点
        with TreeDb do
        begin
           try
           if not Active then open;
           first;
           while not Eof do
           begin
             curID:=trim(FieldByName('tsglb').AsString);
             nodeTxt:=curID+'-'+trim(FieldByName('tsglbn').AsString);
             level:=GetNodeLevel(cTreeCodeFormat,curID);
             //这里返回代码的层次数
             if level>0 then
             begin
      //增加下一节点时,用添加子节点的方法可轻松实现节点间的层次关系。
             //注意:这里的父节点是用当前节点的上一级节点mynode[level-1]
                mynode[level]:=Tree.Items.AddChild(Mynode[level-1],NodeTxt);
                mynode[level].ImageIndex:=2;
                mynode[level].SelectedIndex:=3;
             end;
             next;//下一条记录
           end;
           finally;
             close;
           End;
           mynode[1].expand(False);
           Screen.Cursor:=crHourGlass;
         end;
    end;function TtsgzlFrom.GetNodeLevel(sFormat,sCode:string):integer;
    var i,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;Function TtsgzlFrom.GetNodeItem(sCode:string):integer;//获得item
    var i,iCount,val:integer;
        tmp:string;
    begin
      Result:=0;
      iCount:=Tree.Items.Count;
      if iCount=0 then exit;
      val:=0;
      for i:=1 to iCount-1 do
      begin
         Tmp:=Tree.Items.Item[i].Text;
         Tmp:=Copy(Tmp,0,pos('-',Tmp)-1);
         if Tmp=sCode then begin
            val:=i;
            Break;
         end;
      end;
      result:=val;
    end;procedure TtsgzlFrom.UpdateTree(curNode:TTreenode; nodeTxt:string; state:string);
    Begin
      if  state='add'   then
        begin
          curNode:=Tree.Items.addchild(curNode,nodeTxt);
          curNode.ImageIndex:=2;
          curnode.SelectedIndex:=3;
        end;
      if state='del' then  curNode.delete;
      if state='edi' then  curNode.Text:=nodeTxt;
    end;
      

  4.   

    Bom表結構
    字段名    說明     類型     長度          是否可為Null  是否主鍵 
    Add_ID ID號 INT (自增型)
    ItemNo 產品編碼 VC 50 N Y
    Parent_No 上階編碼 VC 50 N Y
    Code_No 料品編碼 VC 50 N Y當然ItemNo也可不要,但需要時在某些操作上會方便很多及對數據管理也有好處.
    當ItemNo = Parent_No = Code_No 說明這是最終的產品
    Parent_No指向Code_No的父料號項.
    以下是我用的一個遍歷算法,僅供參考:  //在這裡Edit1.Text為產品編碼Procedure TFrmBOM.RefreshTreeNode;  //從後台數據庫中提取數據生成所有結點
    var TreeNode:TTreeNode;
    begin
      TreeView1.Items.Clear;
      TreeNode:=TreeView1.Items.Add (nil,Edit1.Text);
      TreeNode.ImageIndex:=1;
      TreeNode.Selected:=True;
      GetTreeNode(TreeNode); //畫結點
    end;Procedure TFrmBOM.GetTreeNode(Parent_Node:TTreeNode;IsGetChild:Boolean=False); //得到料號下的結點(父項料號)
    var TreeNode:TTreeNode;
    begin
      IF not IsGetChild then
      begin
        with Query5 do
        begin
          Close;
          SQL.Clear;
          SQL.Add('Select Code_No From Bom where ItemNo='+''''+Edit1.Text+''''+
            ' and Parent_No='+''''+Parent_Node.Text+''''+' order by Code_No');
          Open;
        end;
        IF Query5.RecordCount>0 then
        begin
          Query5.First;
          while not Query5.Eof do
          begin
            if Query5.Fields[0].asstring<>Parent_Node.Text then
            begin
              TreeNode:=TreeView1.Items.AddChild(Parent_Node,Query5.Fields[0].asstring);
              TreeNode.ImageIndex:=1;
              TreeNode.SelectedIndex:=3;
              TreeNode.Selected:=true;
            end;
            Query5.Next;
          end;
          IF Parent_Node.GetFirstChild<>nil then
          begin
            GetTreeNode(Parent_Node.GetFirstChild);
          end
          else
          IF Parent_Node.getNextSibling<>nil then
             GetTreeNode(Parent_Node.GetNextSibLing)
          else
             IF Parent_Node.Parent<>nil then GetTreeNode(Parent_Node.Parent,true)
             else Exit;
        end
        else
        begin
          IF Parent_Node.GetNextSibling<>nil then
             GetTreeNode(Parent_Node.GetNextSibLing)
          else
             IF Parent_Node.Parent<>nil then GetTreeNode(Parent_Node.Parent,True)
             else Exit;
        end;
      end;
      IF IsGetChild then
      begin
        IF Parent_Node.GetNextSibling<>nil then
           GetTreeNode(Parent_Node.GetNextSibling)
        else
          IF Parent_Node.Parent<>nil then GetTreeNode(Parent_Node.Parent,True)
          else Exit;
      end;
    end;
      

  5.   

    是不是这样 :
    -----------------------Delphi 
      Delphi 数据库编程
      ...
    其它
      ...如果是可以用两张表 :
    ID Name
    1  Delphi
    2  其它
    ------------
    Ids Names
    1   Delphi数据库编程
    1   Delphi网络编程
    1   ...
    2   其它编程
    ===================================================
    var
      Tn : TTreeNode ;
      Tn1 : TTreeNode ;
      TnArr : Array of TTreeNode ;
      i , j : Integer ;  Tn := TreeView1.Items.Add(Nil,'库') ;
      Tn1 := TreeView1.Items.AddChild(tn,'dddd') ;
      i := 0 ;
      j := 1 ;
      With ADOQuery1 do
      begin
        Close ;
        Sql.Text := 'select Distinct ID from table1 ' ;
        Open ;
        SetLength(TnArr,RecordCount) ;
        While Not Eof do
        begin
          TnArr[i] := TreeView1.Items.AddChild(tn,FieldByName('ID').AsString) ;
          Next ;
          Inc(i) ;
        end;
      
        for i := 0 to RecordCount-1 do
        begin
          With ADOQuery1 do
          begin 
            Close ;
            Sql.Text := 'select Names from Table2 where IDs = '''
                   + TnArr[i].Text  + ''''  ;
            try
              Open ;
            except
            end ;
            While Not Eof do
            begin 
              Try
                TreeView1.Items.AddChild(TnArr[i],FieldByName('Names').AsString) ;
                Next ;
              Except
              End ;
            end ; 
          end ;
        end ;
      end ;
      

  6.   

    按typ_code排序,写入TStrings,然后
    strings.SaveToStream(stream);
    treeview.LoadFromStream(stream);OK
      

  7.   

    SAVE的方法感觉是好
    但是不知道怎么处理
    如果把TREEVIEW中的内容存如TXT
    那格式是这样的01
      0101
          010101
      0102 
          010201
    02
      0201
      0202
    .
    .
    .
    .
    .
    .wjlsmail(计算机质子) 你那个不怎么好啦.
    太局限了嘛~
      

  8.   

    saveToFile也行,saveToStream也一样
    第一层代码直接写,然后每下一层在前面添加一个空格就可以了。