关于节点构造的说明
如有记录为:
MyID MYParentID Mytext
1 0 a
2 1 b
3 1 c
4 2 d
5 2 e
6 5 f
7 6 g
。。。。。。。。。
如果要使1是2,3的父ID,2是4,5的父ID,5是6的父ID,6是的父ID;可构造一个递归函数:
procedure TFROM1.MyNode(MyParentID: string;MyNodeT:TTreeNode);
type
PMyList = ^AList;//声明一个记录,以便临时记录当前树节点;
AList = record
MyParendID: string;//父节点关键词;
MyNodeP: TTreeNode ;//父节点;
end;
var
ATempList: TList;//用于临时保存以上声明的记录类型;
I: Integer;
ARecord:PMyList;
s:string;
node:TTreeNode;
begin
ADOTable1.Filtered:=true;
ADOTable1.Filter:='' MYParentID =''+MyParentID;//筛选符合要求的记录;
if ADOTable1.RecordCount<1 then exit;//终止递归;
ATempList := TList.Create;
try
ADOTable1.First;//保证完整遍历数据;
while not ADOTable1.Eof do
begin
New(ARecord);
s:=''(''+ADOTable1MyID.AsString +'')''+ ADOTable1Mytext.AsString ;
node:= TreeView1.Items.AddChild(MyNodeT ,s) ;//一定要记录下关键字段的ID,以便递归;
ARecord^.MyParendID:= ADOTable1Mytext.AsString ;
Arecord^.MyNodeP :=node;
ATempList.Add(Arecord);//记录临时节点;
ADOTable1.Next;
end;
for I :=0 to ATempList.Count - 1 do
begin
Arecord:=ATempList.Items[i];
MyNode(Arecord^.MyParendID,Arecord^.MyNodeP ); //递归
end;
finally
for I := 0 to ATempList.Count - 1 do
Dispose(ATempList[I]);//清除
ATempList.Free;
ADOTable1.Filtered:=false;
end;
procedure TForm1.FormShow(Sender: TObject);
begin
ADOTable1.DisableControls;
if ADOTable1.Active then
ADOTable1.Active:=false;
ADOTable1.Active:=true;
ADOTable1.First;
MyNode(''0'',nil );//使用递归;构造所有节点;但一定要保证;无父节点的记录其父ID为零;
ADOTable1.EnableControls;
end;
end;
本方法在我的程序TreeView中使用正常(当然实际应用时要有所变通),在构造TreeView节点时可用方法很多,比如构造 1,101,10101,类型的结构,可以很容易的构造TreeView节点,但是这种方法的最不足的是,当树层次很多时,可想而知,作为主关键要设置多大才能满足需要呢?因而不合符一般性,同时如果数据又很多,比如笔者的程序中要显示的记录的八千多个记录,如果以1,101,10101,类型的结构,需如此构造才能合符,1,10001,100010001,。。。。。。。如果有20级,该字段有80个字符!。如果使用笔者提到的cxDBTreeList控件,我以同样的手段构造TreeView节点,在实际运行中,当记录量小时(500个以内)运行良好,但当记录量大于1000个时显示就会相当慢,如果大于6000,其显示等待时间让人难于忍受,(笔者所用的电脑内存512MB,迅驰Ⅱ1.6)经常会出现死机的现象(使用cxDBTreeList控件也一样),打开cxDBTreeList的源代码,发现有如下语句,“if not DataSet.Locate(DataController.ParentField, AKeyValue, []) then Exit; while not DataSet.Eof and (DataController.ParentFieldField.Value = AKeyValue) do”可以断定在数据量很大时,这些语句会相当耗时,因此为了减少查询时间,在我的程序中改为“ADOTable1.Filtered:=true; ADOTable1.Filter:='' MYParentID =''+MyParentID;”;这样一来,显示时间小于三秒(以8000个记录测试),当记录在3000个以内时几乎不会有等待;
本方法的优点是:不用为维护节点ID(因可使用自动ID),不用操心树层次数。改变节点时只改变其父节点ID,因主键ID不会改变,不会影响已有的数据关系。
作者:yangbin(delphi园地中也是这个会员名);
电邮:xftyyyyb@yahoo.com.cn;
QQ号:344709752(不过很少用,因为没时间,^_^);
笔者写这些只想认识更多的朋友,如果你要转载请不要删除以上信息。
Tags:
作者:佚名评论内容只代表网友观点,与本站立场无关!
评论摘要(共 0 条,得分 0 分,平均 0 分)
查看完整评论