用treeview.
具体方法是:创建一个数据库,字段根据实际业务而定,其中必然有一个字段的信息将
在树型控件的节点上显示,另外还要一个字段来保存节点的惟一标识号,该标识号由长
度相等的两部分组成,前段表示当前节点的父节点号,后段表示当前节点的节点号,
此标识号相当于一个“链表”,记录了树上节点的结构。该方法的优点:用户操作
“大树”时,一般不会展开所有的节点,而只用到有限的一部分,同时只能从树根
一层一层地展开,该法只在树上产生“看得见”的节点,所以,存储和加载“大树”
的速度快,数据量小,系统开销和数据冗余较小。缺点:编程较复杂,但可以结合该
方法编成一个新的树控件,将大大提高编程效率。值得注意的是,ID号必须惟一,
所以在编程中如何合理产生ID尤为重要。
数据库结构示例
创建一个数据库,为简化程序,我只创建两个数据库字段,定义如下:
字段名 类型 长度
text c 10
longid c 6
LongID字段实际上由两段组成,每一段3位,LongID只能表示1000条记录。
将LongID定义为索引字段。给数据表新建一条记录,Text字段设为TOP,LongID字段
设为“000”(3个“0”前为三个空格)。 创建演示程序
在Form1上放置TreeView1、Table1、TableName属性设为tree.dbf,IndexFieldNames
属性设为LongID;
在treeunit.pas的Type关键字后加入一行:Pstr:^string;{Pstr为字符串指针}
为Form1的OnCreate事件添加代码:
procedure TForm1.FormCreate(Sender: TObject);
var p
str;Node:TTreeNode;
begin
with Table1,Treeview1 do
begin
open;
first;
new(p);{为指针p分配内存}
p^:=FieldByName(′LongID′).AsString;
Node:=Items.AddChildObject(nil,FieldByName(′Text′).AsString,p);
if HasSubInDbf(Node) then Items.AddChildObject(Node,′ ′,nil);{有子节点则加一个空子节点}
end;
end;
HasSubInDbf为自定义函数,自变量为Node,检查节点Node有无子节点,有则返回True,反之返回False,并在TForm1的类定义里加入原型声明(其它自定义函数的原型也在TForm1的类定义里声明,不另作解释),函数代码如下:
function TForm1.HasSubInDbf(Node:TTreeNode):Boolean;
begin
with Table1 do
begin
Table1.FindNearest([copy(Pstr(Node.Data)^,4,3)+′000′]);
result:=copy(FieldByName(′LongID′).AsString,1,3)=copy(Pstr(Node.Data)^,4,3);{如数据库里当前记录的LongID字段内容的前3位和节点Node的Data的后3位相同,则Node应该有子节点}
end;
end;