您好,欢迎来到[编程问答]网站首页   源码下载   电子书籍   软件下载   专题
当前位置:首页 >> 编程问答 >> Delphi >> 如何动态生成TreeView?

如何动态生成TreeView?

来源:网络整理     时间:2016/8/9 13:58:12     关键词:

关于网友提出的“ 如何动态生成TreeView?”问题疑问,本网通过在网上对“ 如何动态生成TreeView?”有关的相关答案进行了整理,供用户进行参考,详细问题解答如下:

问题: 如何动态生成TreeView?
描述:

数据库的字段为cCode和cText想动态生成TreeView,
cCode的编码规则为第一级为0001,然后第二级的代码为0001.0001,中间有个‘.'作为分割符。
想实现的效果如下:
    0001:北京
          0001.0001:海淀
          0001.0002:怀柔
          0001.0003:通县
    0002:上海
          0002.0001:浦东
          0002.0002:浦西
    0003:天津
          0003.0001:和平
          0003.0002:南开
向大家请教,谢谢!
    


解决方案1:

直接用控件吧!
cxDBTreeView

解决方案2:

如果已经确定了4位数一级的话,那个‘。’作为分隔符已经毫无必要了,因为长度就可以确定级数
数据和程序如下,测试OK
  0001:北京
  00010001:海淀
  00010002:怀柔
  00010003:通县
  0002:上海
  00020001:浦东
  00020002:浦西
  0003:天津
  00030001:和平
  00030002:南开

procedure Tform1.createtree(ado1: tadoquery; name, code: string; tree: Ttreeview; code_len: integer; maxlevel: integer);
var
  cur_level, treeindex: integer;
  current_parent_index: array of integer;
begin
  setlength(current_parent_index, maxlevel);
  treeindex := 0; //这个是当前treeview的item的AbsoluteIndex
  ado1.First;
  while not ado1.Eof do
  begin
    if length(ado1.FieldByName(code).AsString) = code_len then
    begin
      tree.Items.Add(nil, ado1.fieldbyname(name).AsString);
      current_parent_index[0] := treeindex; //
    end
    else
    begin
      cur_level := length(ado1.FieldByName(code).AsString) div code_len; //确定是第几级
      tree.Items.AddChild(tree.Items[current_parent_index[cur_level - 2]], ado1.fieldbyname(name).AsString);
      current_parent_index[cur_level - 1] := treeindex;
    end;
    treeindex := treeindex + 1;
    ado1.Next;
  end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
  treeindex: integer;
  current_parent_index: array[1..15] of integer;
begin
  adoquery1.Active := false;
  adoquery1.SQL.Clear;
  adoquery1.SQL.Add('select name,code from test1 order by code');
  adoquery1.Active := true;
  createtree(adoquery1, 'name', 'code', treeview1, 4, adoquery1.RecordCount);
end;
解决方案3:

create table test_t(ccode varchar2(20),ctext varchar2(20));
insert into test_t
select '0001','北京' from dual
union
select '0001.0001','海淀' from dual
union
select '0001.0002','怀柔' from dual
union
select '0001.0003','通县' from dual
union
select '0002','上海' from dual
union
select '0002.0001','浦东' from dual
union
select '0002.0002','浦西' from dual
union
select '0003','天津' from dual
union
select '0003.0001','和平' from dual
union
select '0003.0002','南开' from dual


unit Unit1;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls, DB, ADODB;
type
  pTVInfo = ^TTVInfo;
  TTVInfo = record
    ccode: String;
    ctext: String;
  end;
type
  TForm1 = class(TForm)
    ADOConnection1: TADOConnection;
    ADOQuery1: TADOQuery;
    TreeView1: TTreeView;
    Button1: TButton;
    ADOQuery2: TADOQuery;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
    FTVInfo: pTVInfo;
  public
    { Public declarations }
  end;
var
  Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
  function AddTreeNode(vTVInfo: pTVInfo;pNode: TTreeNode): TTreeNode;
  var
    vNode: TTreeNode;
  begin
    if pNode=nil then
    begin
      vNode := TreeView1.Items.Add(nil,FTVInfo.ctext);
      vNode.Data := FTVInfo;
    end else
    begin
      vNode := TreeView1.Items.AddChild(pNode,FTVInfo.ctext);
      vNode.Data := FTVInfo;
    end;
    result := vNode;
  end;
var
  pNode: TTreeNode;
begin
  with adoquery1 do
  begin
    close;
    sql.Text := ' select ccode,ctext from test_t where length(ccode)=4 order by to_number(ccode)';
    Open;
    while not eof do
    begin
      new(FTVInfo);
      FTVInfo.ccode := FieldByName('ccode').AsString;
      FTVInfo.ctext := FieldByName('ctext').AsString;
      pNode := AddTreeNode(FTVInfo,nil);
      with adoquery2 do
      begin
        close;
        sql.Text := ' select ccode,ctext from test_t where substr(ccode,1,4)=:ccode and length(ccode)<>4 order by to_number(ccode)';
        parameters.ParamByName('ccode').Value := FTVInfo.ccode;
        open;
        while not eof do
        begin
          new(FTVInfo);
          FTVInfo.ccode := FieldByName('ccode').AsString;
          FTVInfo.ctext := FieldByName('ctext').AsString;
          AddTreeNode(FTVInfo,pNode);
          Next;
        end;
      end;
      Next;
    end;
  end;
end;
end.
解决方案4:

把每条数据设父结点(根结点的父结点为空),首先加根结点、再加第一级结点、依次第二级结点。。。。。。
repeat
  读入数据
  找到父结点,
  加入为子结点
  标记该结点 
util 数据全部加入

解决方案5:

给你一个例子:(CX版的)
自定义过程:

procedure TRES_BOM_VIEW_F.CREATETREEVIEWMODEL;
var
  iLoop:Integer;
  Master,MasterNode:TTreeNode;
begin
  adoq_getop.Close;
  //SELECT distinct PARN_TYP FROM WWW where parn_typ<>'.' and parn_typ is not null order by PARN_TYP desc
  adoq_getop.SQL.Text:='SELECT distinct PARN_TYP FROM WWW where parn_typ<>''.'' and parn_typ is not null order by PARN_TYP desc';
  adoq_getop.Open;
  adoq_getop.First;
  cx_TV.Items.BeginUpdate;
  cx_TV.Items.Clear;
  Master:=cx_TV.Items.Add(nil,'昆盈BOM表检视');
  while not adoq_getop.Eof do
  begin
    if adoq_getop.FieldByName('PARN_TYP').AsString<>'' then
    begin
      Screen.Cursor:=crSQLWait;
      MasterNode:=cx_TV.Items.AddChild(Master,VarToStr(adoq_getop.FieldValues['PARN_TYP']));
      Application.ProcessMessages;
      qry_op.Close;
      qry_op.SQL.Text:='SELECT DISTINCT PARN_LITM FROM WWW WHERE PARN_TYP='''+ VarToStr(adoq_getop.FieldValues['PARN_TYP'])+''' GROUP BY PARN_LITM';
      qry_op.Open;
      for iLoop:=0 to qry_op.RecordCount -1 do
      begin
        cx_TV.Items.AddChild(MasterNode,VarToStr(qry_op.FieldValues['PARN_LITM']));
        qry_op.Next;
      end;
      Application.ProcessMessages;
      cx_TV.Items.EndUpdate;
      Screen.Cursor:=crDefault;
    end;
    adoq_getop.Next;
    Application.ProcessMessages;
  end;
 {
  ThreadTView:=cx_TV;
  ViewThread:=TExpandLH.Create;
  ViewThread.Resume;
  }
end;
点击按钮生成TREE:
procedure TRES_BOM_VIEW_F.btnSB_SearchClick(Sender: TObject);
begin
  inherited;
  try
    RES_LOADING_F:=TRES_LOADING_F.Create(Self);
    RES_LOADING_F.Label1.Caption:='正在检索相关数据......';
    RES_LOADING_F.Show;
    RES_LOADING_F.Update;
    CREATETREEVIEWMODEL;
  finally
    RES_LOADING_F.Close;
  end;
end;

解决方案6:

就两级菜单,遍历吧,先把.之前的唯一记录加上,然后加.后面的

解决方案7:

如果不是严格排序的,可以先排一下序,然后根据编号规则查找父节点,这样效率会高。

解决方案8:

如果你是严格按照顺来的,那就很简单,根据规则依次添加父子节点就行了,如果是乱的,最好先添加最顶级节点,然后再添加下级节点,添加下级时根据编号规则去treeview上找父节点,treeview的node.data可以存储一些标识,以便你查找


以上介绍了“ 如何动态生成TreeView?”的问题解答,希望对有需要的网友有所帮助。
本文网址链接:http://www.codes51.com/itwd/3158021.html

相关图片

相关文章