关于网友提出的“ 如何动态生成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