关于分级加载treeview表的问题,下面这个代码,是一次性加载完的,因为节点多,速度太慢了,我想求大家指点下,如何分级加载节点,点第二层时怎么加载,请在下面的代码上指点一下,改改,在线等,行吗?
数据表(bmda)结构:
bh注:主键)     mc(注:节点名称)     sjbh(属于主键的那层)    URL(对应的页面)
1                     政法网                        0
2                     公安网                        0
3                     律师网                        0
4                     中国政法评论网                1             http://www...
5                     北京市公安局                  2             http://www...
6                     人民律师网                    3             http://www...
function TreeFill1(FTV: Tobject; ID: Integer; TREEDSTNAMESHOW, TREEDSTNAME, TREEDSBHNAME, TREEDSMCNAME, TREEDSSJBHNAME, TREEDSURLNAME, TREEDSVIPNAME: string): Boolean;
var
  TV1: TTreeView;
  TopNode1: TTreeNode;
  TempNode1: TTreeNode;
  S1: array of TMydata1;
  CDS_Tree1: TClientDataset;
  I1, J1, COUNT1: Integer;
  F1: Boolean;
begin
  TV1 := TTreeView(FTV);
  TV1.Items.Clear;
  TV1.ReadOnly := True;
  TopNode1 := TV1.Items.GetFirstNode;
  New(MyData1);
  MyData1^.ID1 := ID;
  MyData1^.BH1 := '';
  MyData1^.MC1 := '';
  MyData1^.SJBH1 := '';
  MyData1^.URL1 := '';
  MyData1^.VIP1 := '';
  TopNode1 := TV1.Items.Add(TopNode1, TREEDSTNAMEShow);
  TopNode1.ImageIndex := 0;
  TopNode1.SelectedIndex := 1;
  TopNode1.Data := MyData1;
  try
    CDS_Tree1 := TClientDataset.Create(DMDATA);
    CDS_Tree1.ProviderName := 'DSP_AQCMD1';
    CDS_Tree1.CommandText := ' SELECT *  FROM ' + TREEDSTNAME + ' ORDER BY ' + TREEDSBHNAME;
    try
      CDS_Tree1.Open;
      COUNT1 := 0;
      COUNT1 := CDS_Tree1.RecordCount + 1;
      if COUNT1 > 1 then
      begin
        SetLength(S1, COUNT1);
        CDS_Tree1.First;
        while not CDS_Tree1.Eof do
        begin
          New(MyData1);
          MyData1^.ID1 := ID;
          MyData1^.BH1 := CDS_Tree1.fieldbyname(TREEDSBHNAME).AsString; ;
          MyData1^.MC1 := CDS_Tree1.fieldbyname(TREEDSMCName).AsString;
          MyData1^.SJBH1 := CDS_Tree1.fieldbyname(TREEDSSJBHNAME).AsString;
          MyData1^.URL1 := CDS_Tree1.fieldbyname(TREEDSURLNAME).AsString;
          MyData1^.VIP1 := CDS_Tree1.fieldbyname(TREEDSVIPNAME).AsString;
          if (MyData1^.SJBH1 = null) or (MyData1^.SJBH1 = '') or (MyData1^.SJBH1 = '0') then
          begin
            //第二层
            TopNode1 := TV1.Items.GetFirstNode;
            TempNode1 := TV1.Items.AddChild(TopNode1, MyData1^.MC1);
            TempNode1.ImageIndex := 0;
            TempNode1.SelectedIndex := 1;
            TempNode1.Data := MyData1;
          end
          else
          begin
             //有上级
            F1 := False;
            for J1 := 0 to TV1.Items.Count - 1 do
            begin
              if TMyData1(TV1.Items[J1].data)^.BH1 = Mydata1^.SJBH1 then
              begin
                F1 := True;
                TopNode1 := TV1.Items[J1];
                TempNode1 := TV1.Items.AddChild(TopNode1, MyData1^.MC1);
                TempNode1.ImageIndex := 0;
                TempNode1.SelectedIndex := 1;
                TempNode1.Data := MyData1;
                Break;
              end;
            end;
            if not F1 then //找不到上级
              S1[CDS_Tree1.RecNo] := Mydata1;
          end;
          CDS_Tree1.Next;
        end;
      end;
except
 on e:exception do
  ShowMessage('打开表出错!'+e.message);
end;
  finally
    CDS_Tree1.Free;
  end;
  //处理未加入树的记录
  for I1 := 0 to COUNT1 - 1 do
  begin
    if S1[I1] <> nil then
    begin
      F1 := FaLSE;
      for J1 := 0 to TV1.Items.Count - 1 do
      begin
        if TMyData1(TV1.Items[J1].data)^.BH1 = s1[i1].SJBH1 then
        begin
          F1 := True;
          TopNode1 := TV1.Items[J1];
          TempNode1 := TV1.Items.AddChild(TopNode1, s1[i1].MC1);
          TempNode1.ImageIndex := 0;
          TempNode1.SelectedIndex := 1;
          TempNode1.Data := s1[i1];
          Break;
        end;
      end;      if not F1 then
      begin
          //加入到第二层
        TopNode1 := TV1.Items.GetFirstNode;
        TempNode1 := TV1.Items.AddChild(TopNode1, s1[i1].MC1);
        TempNode1.ImageIndex := 0;
        TempNode1.SelectedIndex := 1;
        TempNode1.Data := s1[i1];
      end
    end;
  end;
  TV1.FullExpand;
  TV1.FullCollapse;
end;

解决方案 »

  1.   

    晕啊,两颗星星的帮一下忙啊,有自己的实例也可以啊,ACCESS数据库的
    ,我查了好多东西,就是做不出来,差那么一点,给个最简单的例子吧
      

  2.   

    树有很多级,很多节点,一次性加载太慢了,分级加载,展开哪个节点时,加载哪个,不要贴段代码啊,那样我也难看懂,要实例子,ACCESS的,求大侠了
      

  3.   

    可以先将一级,
    设备一级节点的haschildren:=true;在Expanding中建立相关节点的子节点,如果子节点没有数据,则将相应的节点的haschildren:=false;
      

  4.   

    数据表(bmda)结构:
    bh注:主键) mc(注:节点名称) sjbh(属于主键的那层) URL(对应的页面)
    1 政法网 0
    2 公安网 0
    3 律师网 0
    4 中国政法评论网 1 http://www...
    5 北京市公安局 2 http://www...
    6 人民律师网 3 http://www...帮你写一个吧
    procedure buildtree(ANode:TTreeNode;AParentID:integer);
    var
      cds:TClientDataset;
      Node:TTreeNode;
      D:TMydata1;
    begin
      cds:=TClientDataset.create(nil);
      cds.ProviderName := 'DSP_AQCMD1';
      cds.CommandText := ' SELECT * FROM ' + TREEDSTNAME + ' WHERE  sjbh='+inttostr(AParentid)+'  ORDER BY ' + TREEDSBHNAME;
      
      try
         try
             cds.open;
             if cds.eof and cds.bof then 
             begin
                ANode.haschildren:=false;
                exit; 
             end;
             while not cds.eof do 
             begin
                 Node:=TV.item.addchild(ANode,cds.fieldBYname('mc').asstring;
                 new(d);
                 //给D赋值
                 Node.data:=D;
                 Node.haschildren:=true;
                 cds.next; 
             end;
         except
         end;
      finally
       freeandnil(cds);
      end; 
    end;
      

  5.   

    在form show事件中,写上  buildtree(nil,0);
     在,tv(Treeview)的Expanding事件写上代码
    procedure TForm1.TreeView1Expanding(Sender: TObject; Node: TTreeNode;
      var AllowExpansion: Boolean);
    var
      D:TMydata1;
    begin
       if Node.HasChildren and (Node.getFirstChild=nil) then
       begin
          D:=Tmydata1(Node.Data^);//
          buildtree(Node,D.Id);
       end;
    end;
      

  6.   

    lwk_hlj(阿凯(学习oralce中)) 
    您好,谢谢,就是这个意思,临时结点是怎么加还不清楚,能再指点一下吗?本来想现在就结贴的,但是还是有的没搞清楚,想再问一问
      

  7.   

    临时节点就是一个过渡节点
    即用来检测,一个父节点下面已经已经建树了,如我给你的
    在buildtree中改
    Node:=TV.item.addchild(ANode,cds.fieldBYname('mc').asstring;
    new(d);
    //给D赋值
    Node.data:=D;
    Node.haschildren:=true;
    tv.time.addchild(Node,'TEMP');//加入临时节点
    ,tv(Treeview)的Expanding事件写上代码if Node.HasChildren and (Node.getFirstChild<>nil) and (Node.getFirstChild.text='TEMP') then
      Node.DeleteChildren;//删除临时节点
      D:=Tmydata1(Node.Data^);//
    buildtree(Node,D.Id);
      

  8.   

    按你的说法,在
    在form show事件中,写上  buildtree(nil,0);这个地方也要加临时结点吧,不然那不是什么都没有
      

  9.   

    在buildtree中改
    Node:=TV.item.addchild(ANode,cds.fieldBYname('mc').asstring;
    new(d);
    //给D赋值
    Node.data:=D;
    Node.haschildren:=true;
    tv.time.addchild(Node,'TEMP');//加入临时节点这不是已经加上了吗?
      

  10.   

    你可以先不加Expanding事件看看有什么效果!
      

  11.   

    嗯,上面的我说错了,不好意思tv.item
    tv.time报错,treeview没有这两个属性啊
      

  12.   

    我晕,建树的代码都没问题了,数据库连不上,可能我的连法有问题,ADO的
    procedure TForm2.FormCreate(Sender: TObject);
    const
      FrmConStrA1 = 'Provider=Microsoft.Jet.OLEDB.4.0;Jet OLEDB:Database Password="%s";Data Source="%s"';
      var
      constra1: string;
      begin
      ConStrA1 := Format(FrmConStrA1, ['', ExtractFilePath(Application.ExeName) + 'pp1.mdb']);
      with DMDATA.ADOCON1 do
      begin
        close;
        ConnectionString := constra1;
        open;
      end;
    end;
      

  13.   

    太简单,定义一个节点指针,
    TNodeData = ^ NodeData;
    NodeData = record 
      fId  : integer;  //current node id
      fInfo : string;  //current node message info 
      fUpId : integer  //up level node id
    end;//........................
      

  14.   

    都差不多了,就是打开时,提示FORM这句SQL出错,我把你那跟连接有关的语句反复改了一些,还是不行,不晓得错在哪里procedure buildtree(ANode:TTreeNode;AParentID:integer);
    var
      TV1: TTreeView;
      CDS_Tree1: TClientDataset;
      Node:TTreeNode;
      D:TMydata1;
      TREEDSTNAME, TREEDSBHNAME: string;
    begin
      TV1 := TTreeView(ANode);
      try
        CDS_Tree1:= TClientDataset.Create(DMDATA);
        CDS_Tree1.ProviderName := 'DSP_AQCMD1';
        CDS_Tree1.CommandText := ' SELECT * FROM ' + TREEDSTNAME + ' WHERE  sjbh='+inttostr(AParentid)+'  ORDER BY ' + TREEDSBHNAME;     try
             CDS_Tree1.open;
             if CDS_Tree1.eof and CDS_Tree1.bof then
             begin
                ANode.haschildren:=false;
                exit;
             end;
             while not CDS_Tree1.eof do
             begin
                 Node:=TV1.items.addchild(ANode,CDS_Tree1.fieldBYname('mc').asstring);
                 new(d);
                 //给D赋值
                 Node.data:=D;
                 Node.haschildren:=true;
                 tv1.items.addchild(Node,'TEMP');//加入临时节点
                 CDS_Tree1.next;
             end;
         except
         end;
      finally
       freeandnil(CDS_Tree1);
      end;
    end;
    procedure TForm2.FormCreate(Sender: TObject);
    const
      FrmConStrA1 = 'Provider=Microsoft.Jet.OLEDB.4.0;Jet OLEDB:Database Password="%s";Data Source="%s"';
      var
      constra1: string;
      begin
      ConStrA1 := Format(FrmConStrA1, ['', ExtractFilePath(Application.ExeName) + 'mdb.mdb']);
      with DMDATA.ADOCON1 do
      begin
        close;
        ConnectionString := constra1;
        open;
      end;
      buildtree(nil,0);
    end;
      

  15.   

    嗯,上面的我说错了,不好意思tv.item
    tv.time报错,treeview没有这两个属性啊是item,我打错了!
      

  16.   

    procedure buildtree(ANode:TTreeNode;AParentID:integer);
    var
      TV1: TTreeView;
      CDS_Tree1: TClientDataset;
      Node:TTreeNode;
      D:TMydata1;
    begin
      TV1 := TTreeView(ANode);
      try
        CDS_Tree1:= TClientDataset.Create(DMDATA);
        CDS_Tree1.ProviderName := 'DSP_AQCMD1';
        CDS_Tree1.CommandText := ' SELECT * FROM ' + 'bmda' + ' WHERE  sjbh='+inttostr(AParentid)+'  ORDER BY ' + 'bh';     try
             CDS_Tree1.open;
             if CDS_Tree1.eof and CDS_Tree1.bof then
             begin
                ANode.haschildren:=false;
                exit;
             end;
             while not CDS_Tree1.eof do
             begin
                 Node:=TV1.items.addchild(ANode,CDS_Tree1.fieldBYname('mc').asstring);
                 new(d);
                 //给D赋值
                 Node.data:=D;
                 Node.haschildren:=true;
                 tv1.items.addchild(Node,'TEMP');//加入临时节点
                 CDS_Tree1.next;
             end;
         except
         end;
      finally
       freeandnil(CDS_Tree1);
      end;
    end;
    procedure TForm2.FormCreate(Sender: TObject);
    const
      FrmConStrA1 = 'Provider=Microsoft.Jet.OLEDB.4.0;Jet OLEDB:Database Password="%s";Data Source="%s"';
      var
      constra1: string;
      begin
      ConStrA1 := Format(FrmConStrA1, ['', ExtractFilePath(Application.ExeName) + 'pp1.idx']);
      with DMDATA.ADOCON1 do
      begin
        close;
        ConnectionString := constra1;
        open;
      end;
      buildtree(nil,0);
    end;
                 Node:=TV1.items.addchild(ANode,CDS_Tree1.fieldBYname('mc').asstring);这一行非要报出错,唉,一天了,还没搞完
      

  17.   

    我曾遇到过速度问题 创建1000个节点 treeview的速度 大大慢于 tfcTreeview建议用这个1stclass的控件
      再者算法上 如果级多 减少查找的次数   没有时间看你的代码