我想在一个TreeView控件中显示一棵树,该树如下:
   商品
      |-家电类
             |-电视机类
             |-冰箱类
      |—食品类
             |—奶粉类
             |—水果类
             |—其它类
        。
        。
        。
 每个类的下级分类都有是不确定数,如何设计表及显示出来。

解决方案 »

  1.   

    表设计如下:
    parentid,id
    家电类,电视机类
    家电类,冰箱类
    电视机类,TCL
    电视机类,康佳
    。。
    当然,你可以用代号来代表你的这些名称
    其实这就是二维表的BOM结构
    。。然后在展树的时候递归实现,论坛上很多这样的问题,给你一段的代码:
    这是一段加载树的代码
    function TForm1.ShowTree(TNode: TTreeNode; s: string): boolean;
    var
      QR:TADOQuery;
      TmpNode:TTreeNode;
      p:pchar;
    begin
      QR:=TADOQuery.Create(self);
      if TNode=nil then //判断是否顶层接点 ;
      begin
        new(p);
        p^.mcaption:='';
        p^.tcaption:=s;
        p^.num:=1;
        TNode:=Treeview1.Items.AddChildObject(TNode,p^.tcaption,p);
      end;
      with QR,treeview1 do
      begin
        Items.BeginUpdate;
        close;
        connection:=ADOCONNECTION1;
        SQL.Clear;
        SQL.Add('select MD003,MD006 from BOMMD where MD001=:NN');
        parameters[0].Value:=s;
        open;
        ACTIVE;
        first;
        while not eof do
        begin
          new(p);
          p^.mcaption:=s;
          p^.tcaption:=QR.fieldbyname('MD003').AsString;
          P^.num:=QR.fieldbyname('MD006').AsInteger;
          TmpNode:=Items.AddChildObject(TNode,p^.tcaption,p);
          ShowTree(TmpNode,p.tcaption);
          next;
        end;
      Items.EndUpdate;
      end;
    end;
    下面是一段删除选中节点及子节点的代码(同时删除数据库中对应数据):
    procedure TForm1.detree(node: ttreenode);
    var
      tnode:ttreenode;
      i:integer;
      s1,s2:string;
    begin
      if node.HasChildren then
      begin
        for i:=node.Count-1 downto 0 do
        begin
          if node.Item[i].HasChildren then
          detree(node.Item[i]);
          s1:=pchar(node.Item[i].Data)^.mcaption;
          s2:=pchar(node.Item[i].data)^.tcaption;
          with form1.pub do
          begin
            close;
            sql.Clear;
            sql.Add('delete BOMMD where MD001=:AA and MD003=:BB');
            parameters[0].Value:=s1;
            parameters[1].Value:=s2;
            ExecSQL;
          end;
          node.Item[i].Delete;
        end;
      end;
      node.Delete;
    end;
      

  2.   

    type
      FNodeInfo=^TNodeInfo;    //指针类型,存储对应节点信息
        TNodeInfo=Packed Record
           NodeId:String;        //节点
           NodeName:string;      //节点名称
           ParentId:string;      //父节点
        end;
    procedure TFa_FDepartment.InitTree(Id: string; ParentNode: TTreeNode ;DTree:TTreeView;adoconn:tadoconnection);
    var
        QryTmp:TadoQuery;
        MyNode,pernode:TTreeNode;
        TmpNodeInfo:FNodeInfo;
    begin
        QryTmp:=TadoQuery.Create(nil);
        QryTmp.Connection :=adoconn;
        QryTmp.SQL.Add('Select * from HR_ORGANISESTRUCTURE');
        qrytmp.sql.add(' where SuperiorDept='''+Id+''''+' Order by SuperiorDept');
        QryTmp.Open;
        MyNode:=nil;
        while not QryTmp.Eof do
        begin
          New(TmpNodeInfo);
          TmpNodeInfo.Nodeid:=Trim(QryTmp.Fields[1].AsString);
          TmpNodeInfo.Parentid:=Trim(QryTmp.Fields[6].AsString);
          TmpNodeInfo.Nodename:=Trim(QryTmp.Fields[2].AsString);
          MyNode:=DTree.Items.AddChildObject(ParentNode,QryTmp.Fields[2].AsString,TmpNodeInfo);  //把所有节点当作子节点遍历
          mynode.ImageIndex:=0;
          InitTree(QryTmp.Fields[1].AsString ,MyNode,DTree,adoconn); //递归调用
          QryTmp.Next;
        end;
        QryTmp.Free;
    end;
      

  3.   

    --建立分类号关系表 
    If object_id("sortt") is not null 
       drop table sortt 
    go
    create table sortt 
    (
       sortid int primary key,         --分类号 
       motherid int null,              --母类号 
       name varchar(40) not null,      --类别名称 
       c1 varchar(200) null            --备注 
    )
    go
      

  4.   

    其实 wdsimon() 说法是对了,只是在实现方法上不需要进行递归
    一次仅仅展开一级的信息,需要展开下一级的信息,可以通过展开节点来生成下一层节点的信息
      

  5.   

    表结构:
    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 yourtable'
      query.Open;
      
      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;基本如上,根据以前项目里的一段代码改的,没有调试,你自己在斟酌一下吧!
      

  6.   

    在FillTree(nil,0)调用之前加:TreeView1.BeginUpdate
      

  7.   

    http://expert.csdn.net/Expert/topic/2489/2489919.xml?temp=.5750391有一例