我想用TTreeView与数据库连接,在TTreeView里将数据库表显示为树形结构。
我从网上找到一个很不错的例子,例子的主要代码如下(因忘了记下下载地址,该网站又无法上传附件,所以只贴上主要代码)。form上主要控件有TreeView1、ADOQuery1、ImageList1等,ImageList1里已经加上4个.ico图标,其他各个控件都设置好了。数据库表的结构主要是:
id号  国家名称  城市名称  公司名称
1     美国      城市1     公司1
2     美国      城市1     公司2
3     美国      城市1     公司3
4     美国      城市2     公司1
5     美国      城市2     公司2
6     英国      城市1     公司1
7     英国      城市1     公司2通过下面代码执行后在TTreeViews上显示如下的树结构:
美国
    城市1
         公司1
         公司2
         公司3
    城市2
         公司1
         公司2
英国
    城市1
         公司1
         公司2
............例程的原代码能在上面树结构的每个级别节点名称之前显示不同的图标,但是,拷到我的程序后,各级别节点名称之前只显示ImageList1的第0号图标,不知道为什么?主要代码如下:procedure TForm1.TreeView1Change(Sender: TObject; Node: TTreeNode);
begin
     Datasource1.enabled := Node.data <> nil;
     if DataSource1.enabled then Table1.gotobook(node.data);
end;procedure TForm1.FormCreate(Sender: TObject);
begin
     FieldList := TStringList.create;
     TreeView1.items.BeginUpdate;
     ADOQuery1.first;
     while not ADOQuery1.eof do
     begin
       TreeAddItem(TreeView1, GetFieldList, ADOQuery1.getBook, false);
       ADOQuery1.next;
     end;
     FieldList.clear;
     TreeView1.Alphasort;
     TreeView1.items.Endupdate;
     TreeView1.items[2].selected := true;
end;function TForm1.GetFieldList: TStringList;
begin
     FieldList.clear;
     FieldLis.add(ADOQuery1.fieldbyname('Country').asstring);
     FieldList.add(ADOQuery1.fieldbyname('city').asstring);
     FieldList.add(ADOQuery1.fieldbyname('Company').asstring);
     Result := FieldList;
end;function TreeAddItem(Sender: TTreeView; ItemList: TStrings; Book: TBook; Resort: Boolean): TTreeNode;
var
   ThisNode, Node: TTreeNode;
   I: Integer;
begin
     Node := nil;   //nil = level 0 has no parent node
                    //this is checked by TreeFindItem
     for I := 0 to Itemlist.count -1 do
     begin
          ThisNode := TreeFindItem(Sender, node, Itemlist[i]);
          if ThisNode <> nil then Node := ThisNode else
          begin
               if I < Itemlist.count -1 then
               begin
                    if I = 0 then Node := Sender.items.Add(Node, Itemlist[i])
                    else Node := Sender.items.AddChild(Node, Itemlist[i]);
               end else
               begin
                    if I = 0 then Node := Sender.items.AddObject(Node, Itemlist[i], Book)
                    else Node := Sender.items.AddChildObject(Node, Itemlist[i], Book);
               end;
               Node.stateIndex := Node.level + 1;
               if Resort and (Node.parent <> nil) then Node.parent.alphasort; 
          end;
     end;
     Result := Node;
end;function TreeFindItem(Sender: TTreeView; NodeItem: TTreeNode; Name: String): TTreeNode;
begin
     if NodeItem = nil then NodeItem := Sender.items.getfirstnode
     else NodeItem := NodeItem.getfirstchild;
     if (NodeItem <> nil) and (NodeItem.text <> Name) then
     repeat
           NodeItem := NodeItem.getnextsibling;
     until (NodeItem = nil) or (NodeItem.text = Name);
     Result := NodeItem;
end;

解决方案 »

  1.   

    代码执行后是下面这样的(国家名称、城市名称、公司名称处于不同的层级),奇怪,发到网上后,怎么结构变了。通过下面代码执行后在TTreeViews上显示如下的树结构:
    美国
          城市1
               公司1
               公司2
               公司3
         城市2
               公司1
               公司2
    英国
          城市1
               公司1
               公司2
    ............
      

  2.   

    Ttreenode有iamgelist和statelist两个显示icon的机会
      

  3.   

    我找到了事例的一个下载地址,请大家帮助研究一下,树节点图标怎么不会虽树层级的变化而变化,告诉我一下。
    http://www.jpcode.com/code/740/742/25844.htm
      

  4.   

    树节点图标 与 树层级 没有关系
    是Ttreenode的image/statindex确定的
      

  5.   

    图标是单独设置的,和第几级无关,
    设置Ttreenode的image/statindex和相对应的Timagelist中的index
      

  6.   

    加到100分了。问题的要点:
    数据库表的结构主要是:
    id号 国家名称 城市名称 公司名称
    1 美国 城市1 公司1
    2 美国 城市1 公司2
    3 美国 城市1 公司3
    4 美国 城市2 公司1
    5 美国 城市2 公司2
    6 英国 城市1 公司1
    7 英国 城市1 公司2将上面的表用TTreeView表示出来,而且,要在国家名称上面再加一个顶层,每一层用不同的图表
      

  7.   

    __fastcall TFrm_Main::CreateSubTree(AnsiString Fid,TTreeNode *node)
    {
       AnsiString id,textname;
       TBook  bmk;
       ADODS->Filter="Address_Father="+Fid;
      // Edit1->Text=;
     //ShowMessage(ADODS->RecordCount);
       while (!ADODS->Eof)
       {  id = ADODS->FieldByName("Address_ID")->AsString;
         textname=ADODS->FieldByName("Address_Name")->AsString;
          node = Tree_User->Items->AddChild(node,textname);
          node->ImageIndex=2;
           bmk = ADODS->GetBook() ;
          CreateSubTree(id,node);
          node =node->Parent;
          ADODS->Filter="Address_Father="+Fid;
          if (ADODS->BookValid(bmk))
             {
              ADODS->GotoBook(bmk);
              ADODS->FreeBook(bmk);
              }
          ADODS->Next();
       }
       return (true);
    }
    这是个CB的程序你把它改为一个过程吧
      

  8.   

    模仿着改一下。图标要单独添加,程序不会自动关联的。begin
              ThisNode := TreeFindItem(Sender, node, Itemlist[i]);
              if ThisNode <> nil then Node := ThisNode else
              begin
                   if I < Itemlist.count -1 then
                   begin
                        if I = 0 then 
                            begin 
                                Node := Sender.items.Add(Node, Itemlist[i]);
                                Node .ImageIndex := 1;
                            end
                        else 
                             begin
                                Node := Sender.items.AddChild(Node, Itemlist[i]);
                                Node .ImageIndex := 2;
                             end;
                   end else
                   begin
                        if I = 0 then Node := Sender.items.AddObject(Node, Itemlist[i], Book)
                        else Node := Sender.items.AddChildObject(Node, Itemlist[i], Book);
                   end;
                   Node.stateIndex := Node.level + 1;
                   if Resort and (Node.parent <> nil) then Node.parent.alphasort; 
              end;
         end;
      

  9.   

    又看了一下,改这一处就可以了
    begin
         Node := nil;   //nil = level 0 has no parent node
                        //this is checked by TreeFindItem
         for I := 0 to Itemlist.count -1 do
         begin
              ThisNode := TreeFindItem(Sender, node, Itemlist[i]);
              if ThisNode <> nil then Node := ThisNode else
              begin
                   if I < Itemlist.count -1 then
                   begin
                        if I = 0 then Node := Sender.items.Add(Node, Itemlist[i])
                        else Node := Sender.items.AddChild(Node, Itemlist[i]);
                   end else
                   begin
                        if I = 0 then Node := Sender.items.AddObject(Node, Itemlist[i], Book)
                        else Node := Sender.items.AddChildObject(Node, Itemlist[i], Book);
                   end;
                   Node.stateIndex := Node.level + 1;
                    Node.ImageIndex:= Node.level ;               if Resort and (Node.parent <> nil) then Node.parent.alphasort; 
              end;
         end;
         Result := Node;
    end;
      

  10.   

    既然楼主已经加分,看来你对问题还算重视。iid为全局变量,初值为零。
    然后if Node.level=0 then//如果是根结点(国家节点) 
      begin
         Node.ImageIndex:= iid ;//指定图标,iid的最大值不能超过ImageList1中的图标数。
         inc(i);
      end;另外就是要注意TreeView要与ImageList关联。
      

  11.   

    if Node.level=0 then//如果是根结点(国家节点)  
      begin
      Node.ImageIndex:= iid ;//指定图标,iid的最大值不能超过ImageList1中的图标数。
      inc(iid);
      end;
      

  12.   

    不知道是不是LZ想要的,我这里分四级,四级图标不同,但同级的却是一样的:Nodea := rztvMainFrm.Items.AddChildFirst(nil, '全部小区');
    Nodea.ImageIndex := 6;
    Nodea.SelectedIndex := 7;AreaName := FieldByName('AREANAME').AsString;
    HouseName := FieldByName('HOUSENAME').AsString;
    HouseNo := FieldByName('HOUSENO').AsString;
    Nodeb := rztvMainFrm.Items.AddChild(Nodea, FieldByName('AREANAME').AsString);
    Nodeb.ImageIndex := 8;
    Nodec := rztvMainFrm.Items.AddChild(Nodeb, FieldByName('HOUSENAME').AsString);
    Nodec.ImageIndex := 9;
    Noded := rztvMainFrm.Items.AddChild(Nodec,FieldByName('HOUSENO').AsString);
    Noded.ImageIndex := 10;对于分级,我的处理是在信息登记的时候根据小区+楼幢+房间号生成一个编号,在TreeView显示的时候,先根据这个编号index,再处理。