今天重点学习了TreeView的使用方法,基本的已经写了,现在主要想说的是如何显示数据库的资料,今天只是做了个较简单的例子,一个父节点下显示数据库中某个field的值。代码如下:
procedure TMainForm.TreeviewShow(Sender: TObject);
var
node1,subnode1: TTreeNode;
i: Integer;
begin
Treeview1.Selected := nil;
node1 := Treeview1.Items.AddFirst(nil,'user');
ADOTable1.Active := True;
while not ADOTable1.Eof do
for i := 0 to ADOTable1.RecordCount - 1 do
begin
Treeview1.Items.AddChildObject(node1, ADOTable1.FieldByName('USERNAME').AsString, nil);
ADOTable1.Next;
end;
end;
使用的是ADO中的ADOTable1来完成。
心得:今天下午比较重要的心得或许就是当你在某个函数中写代码的时候,它会自动把那些不符合它返回值的函数功能屏蔽掉。打个比方,象Treeview1.Items.AddChildObject(node1, ADOTable1.FieldByName('USERNAME').AsString, nil);中的第二项,它要求的是返回String ,如果你使用得失ADODATASET的话,它就自动帮你屏蔽掉了FieldByName这个功能,因为返回的不是String,所以,在这种情况下最好是把你需要的函数在空白处得到在copy到里面去。
每一个节点下子节点形成这一节点的Items属性,当前节点有一个唯一的Index(TreeNode的Index属性),用于说明子节点在Items中的位置,每一个节点下的子节点是顺序编号的,第一个是0,第二个是1,依次类推。用IndexOf方法获得子节点的顺序,绝对顺序(AbsoluteIndex)则是指从Treeview第一个项开始的顺序值,第一个是0,如此推下去。Item属性则根据Index的值返回当前节点的第Index个子节点。Count则表明属于此项的所有子节点的数量。用MoveTo方法将Item由一个位置移到另一个位置。
Expanded属性表明是否所有的子项都全部展开(包括子项的子项),为True表示全部展开。IsVisible属性表明一个项是否在树中能被看到,如果树全部展开那么这个Item是肯定可以被看到。HasChildren属性表明一个项是否有子项。 GetFirstChild, GetLastChild, GetPrevChild, and GetNextChild分别返回当前项子项的第一个、最后一个和前一个、后一个项。GetNextSibling and GetPrevSibling则返回在同一Level下的下一个和上一个项。GetNextVisible and GetPrevVisible则返回能看得到的下一个和上一个项。如果一个节点有Parent,则HasAsParent方法返回True. Parent为当前项的父项。Focused属性确定焦点是否落在此节点上,被Focus时会一个标准的方框围住。很显然,只有一个节点会被聚焦。 Selected属性表明一个节点是否被选中,同样只有一个节点会被选中。DropTarget属性表明节点在拖动操作中是源还是目标。
.1.添加、删除、修改节点:
静态的方法可以在设计时通过Items的编辑器设置各节点的内容。
在添加和删除前必须保证有节点被选中(Treeview.Selected = nil)
用AddFirst, AddFirstChild, AddChild等先添加根节点,如Treeview.Items.AddFirst( nil, 'Root');
然后以此为基础,添加此项的子节点。
删除节点
Treeview.Selected.Delete
编辑节点内容
Treeview.Selected.EditText
注意:由于根节点没有父节点 (TTreeNode.Parent= nil)
此外,在大批量添加数据到Treeview中时最好使用
TreeView.Items.BeginUpdate;
添加节点
TreeView.Items.EndUpdate
这样能加快显示速度。
2.在节点上添加图象
Treeview中几个与图象相关的属性:
SelectedIndex:当节点被选中时在TimageList 中选什么样的图象
OverlayIndex:选那副图象作为掩图(一幅图象透明地显示在另一幅图象的前面),比如一个节点不可用时加一副X图象在其前面。
ImageIndex:在常态时选用的图的序号
StateIndex: 在StateImages这个ImageList中对应的序号,-1时不显示图象
比较典型的,象在文件管理器中的所显示的一样,Treeview控件在节点之前也可以显示图象。在Form中放置一ImageList控件,加入几个图片,分别被Index为0,1,…在Treeview的Image属性项填入你所加入的ImageList的控件名称。TreeNode的ImageIndex表示节点未被选中时(Selected=nil)的图片序号,SelectedIndex表示节点被选中时图片序号。
加入父节点使用的命令是Treeview.Items.AddFirst(nil,'father');里面的nil的意思是初始标记(不是0的意思,0已经代表了建立了一个关于节点的对象了,nil代表的是初始化时候的一个node)。在使用该函数来创建节点的时候,你会发现很多例子中都会建立一个TTreeNode对象来把刚才建立父节点的命令赋给这个对象,比如现在有个TTreeNode对象node1,那么就可以写成node1 := Treeview1.Items.AddFirst(nil,'father'),目的是把该节点的标识位置赋予node1,这里不需要再写多一个相同的AddFirst了,因为在赋予node1的同时就已经建立了这个父节点了。那为什么需要这个node1呢?当然,如果你只有一层节点没有子节点的话,可以不需要这个,这个node1主要是为了给建立子节点的时候给它一个标识,告诉系统这个子节点是属于哪个父节点的,命令如下reeview1.Items.AddChildObject(node1, 'child', nil);
编程心得
1,在Delphi中,TreeView控件是一款很出色而且很常用的控件。
在使用过程中,了解到其TTreeNode对象的data属性存储相关数据很有用,一般情况下,我们先声明一个结构体以及其指针,例如:
type
PMyRc = ^TMyRc;
TMyRc = Record
id:string;
name:string;
age:integer;
end;
添加一个节点,显示信息为TMyRc的name,同时存储id,age。方法如下:
var
p:PMyRc;
i:integer;
begin
Randomize;
for i:= 0 to 9 do
begin
New(p);
p.id:=inttostr(random(100));
p.name:='name'+ inttostr(random(205));
p.age:=random(90);
// Caption := p.id+' '+P.name + ' '+inttostr(p.age);
TreeView1.Items.AddObject(nil,p.name,Tobject(p));
//dispose(p); 如果在这里释放指针,id,age并不能存在树中,而是在这里就被释放了。应该在释放树的事件里书写。
end;
end;
释放树的事件deletion, 即使是删除也会执行这些代码。所以不用担心内存泄漏。但是如果不书写以下代码,或者用相关的方式释放内存,必定会造成内存泄漏。
procedure TForm1.TreeView1Deletion(Sender: TObject; Node: TTreeNode);
begin
dispose(pmyrc(node.data));
end;
访问某个树枝中的age值:
Pmyrc(TreeView1.Selected.data)^.age