Delphi TreeView 基础与技巧(详解)

?Delphi TreeView 基础与技巧(详解)

TreeView由节点构成,建树通过对TreeView.items属性进行操作。

Items是一个TTreeNodes对象,这是一个TTreeNode集。

关于TTreeNodes
一、属性
TTreeNodes,也就是TreeView.Items的属性:
1、count,节点个数。
2、item[index] ,通过index得到节点。

二、添加节点的操作
TTreeNodes常用的添加节点的操作有:
Add、AddFirst、AddChild、AddChildFirst
function Add(Node: TTreeNode; const S: string): TTreeNode;
function AddFirst(Node: TTreeNode; const S: string): TTreeNode;
function AddChild(Node: TTreeNode; const S: string): TTreeNode;
function AddChildFirst(Node: TTreeNode; const S: string): TTreeNode;
!!! AddFirst 和 AddChildFirst 是专门插入第一个的

三、得到节点的操作
TTreeNodes常用的得到节点的操作有:
TTreeNode.GetFirstNode() :得到根节点。
TTreeNode.GetNext():得到下一节点

四、事件:
TTreeView.OnChange事件:从一个节点跳到另一个节点时
TTreeView.onEdit事件:修改一个节点的text时



关于TTreeNode
每个TTreeNode,有个Data属性,可以存放一个指针

一般使用流程:
1、添加全局变量:b_first:boolean;
//记录是否是第一次访问节点,因为此时数据还未准备好,而一旦访问节点就会触发OnChange事件,在此事件处理函数中也许会出错。
2、在FormCreate中,
a、设置
b_first:=true;
b. 创建数并将节点与数据联系。
3、在FormShow中设置
b_first:=false;
4.在事件OnChange中处理节点被选中事件。
5.在Edit中处理节点被修改Text事件。 并调用OnChange.
6.在TreeView.Destory中释放Data中指向的内存空间。

如下:
1.我们先定义一个数据结构,作为记录我们要记录的数据。如:
type
PMyData=^TMyData;
TMyData=Record
sFName:string;
sLName:String;
nIndex:integer;
end;

2.然后,创建数时,将节点和节点数据联系起来:
procedure TForm1.Button1Click(Sender: TObject);
var
myshuju: PMyData
cur_node:TTreeNode;
begin
New(myshuju);//记住,一定要先分配内存。有几个节点,就要分配几次内存。
myshuju^.FName:=Edit1.Text;
Myshuju^.LName:= Edit2.Text;
TreeViewIndex:= StrToInt(Edit3.Text);
with TreeView1 do
begin
cur_node:=items.AddFirst(nil,first);
cur_node.data:=myshuju;
end;
end;

3.当我们选中一个节点时,就可以使用我们的数据了。
procedure TForm1.TreeView1Change(Sender:TObject;Node:TTreeNode);
begin
if node.data<>nil then
https://www.360docs.net/doc/ef11611552.html,bel1.caption:=pmyData(node.data)^.Fname+pmyData(node.data)^.Lname
end;

4.内存释放
procedure TForm1.ListView1Deletion(Sender: TObject; Item: TListItem);
begin
Dispose(Item.Data);
end;




建树例子
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes

, Graphics, Controls, Forms,
Dialogs, ComCtrls, StdCtrls;

type
TForm1 = class(TForm)
TreeView1: TTreeView;
Button1: TButton;
Button2: TButton;
Button3: TButton;
Button4: TButton;
Button5: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure Button5Click(Sender: TObject);
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

{方法1: 按职务顺序入场}
procedure TForm1.Button1Click(Sender: TObject);
var
Nodes: TTreeNodes;
node: TTreeNode;
begin
Nodes := TreeView1.Items;

{添加第一个元素}
node := Nodes.Add(nil, '一连长'); {'一连长'好孤独, 旁边没人}

{现在 node 代表"一连长", 继续添加与其平级人员, 当然要参照"一连长"}
Nodes.Add(node, '二连长');
Nodes.Add(node, '三连长');

{安排"一连"的下一层: "排长"; 同时让 node 指向"一排长"}
node := Nodes.AddChild(node, '一排长');
Nodes.Add(node, '二排长');
Nodes.Add(node, '三排长');

{添加平级用 Add, 添加下级用 AddChild; 继续:}
node := Nodes.AddChild(node, '一班长');
Nodes.Add(node, '二班长');
Nodes.Add(node, '三班长');

{还有 AddChildFirst 和 AddFirst 是专门添加第一个的, 假如忘了第一个...}
node := Nodes.AddChild(node, '战士2');
Nodes.Add(node, '战士3');
Nodes.Add(node, '战士4');
Nodes.AddFirst(node, '战士1'); {用 AddFirst 可以让它站在前面}
end;


{方法2: 按先后顺序入场}
procedure TForm1.Button2Click(Sender: TObject);
var
Nodes: TTreeNodes;
node: TTreeNode;
begin
Nodes := TreeView1.Items;

node := Nodes.Add(nil, '一连长');
node := Nodes.AddChild(node, '一排长');
node := Nodes.AddChild(node, '一班长');
node := Nodes.AddChild(node, '战士1');
Nodes.Add(node, '战士2');
Nodes.Add(node, '战士3');
Nodes.Add(node, '战士4');

node := node.Parent; {让 node 指向上一层}
Nodes.Add(node, '二班长');
Nodes.Add(node, '三班长');

node := node.Parent;
Nodes.Add(node, '二排长');
Nodes.Add(node, '三排长');

node := node.Parent;
Nodes.Add(node, '二连长');
Nodes.Add(node, '三连长');
end;


{方法3: 因为没使用 TTreeNodes 和 TTreeNode, 挺麻烦的}
procedure TForm1.Button3Click(Sender: TObject);
begin
TreeView1.Items.Add(nil, '一连长');
TreeView1.Items.Add(TreeView1.Items[0], '二连长');
TreeView1.Items.Add(TreeView1.Items[0], '三连长');

TreeView1.Items.AddChild(TreeView1.Items[0], '一排长');
TreeView1.Items.Add(TreeView1.Items[0].Item[0], '二排长');
TreeView1.Items.Add(TreeView1.Items[0].Item[0], '三排长');

TreeView1.Items.AddChild(TreeView1.Items[0].Item[0], '一班长');
TreeView1.Items.Add(TreeView1.Items[0].Item[0].Item[0], '二班长');
Tree

View1.Items.Add(TreeView1.Items[0].Item[0].Item[0], '三班长');

TreeView1.Items.AddChild(TreeView1.Items[0].Item[0].Item[0], '战士1');
TreeView1.Items.Add(TreeView1.Items[0].Item[0].Item[0].Item[0], '战士2');
TreeView1.Items.Add(TreeView1.Items[0].Item[0].Item[0].Item[0], '战士3');
TreeView1.Items.Add(TreeView1.Items[0].Item[0].Item[0].Item[0], '战士4');
end;


{方法4: 用 with 简化了"方法3", 也够绕的; 推荐使用前两种方法}
procedure TForm1.Button4Click(Sender: TObject);
begin
with TreeView1 do begin
Items.Add(nil, '一连长');
Items.Add(Items[0], '二连长');
Items.Add(Items[0], '三连长');

Items.AddChild(Items[0], '一排长');
Items.Add(Items[0].Item[0], '二排长');
Items.Add(Items[0].Item[0], '三排长');

Items.AddChild(Items[0].Item[0], '一班长');
Items.Add(Items[0].Item[0].Item[0], '二班长');
Items.Add(Items[0].Item[0].Item[0], '三班长');

Items.AddChild(Items[0].Item[0].Item[0], '战士1');
Items.Add(Items[0].Item[0].Item[0].Item[0], '战士2');
Items.Add(Items[0].Item[0].Item[0].Item[0], '战士3');
Items.Add(Items[0].Item[0].Item[0].Item[0], '战士4');
end;
end;


procedure TForm1.Button5Click(Sender: TObject);
begin
TreeView1.Items.Clear;
TButton(Sender).Caption := '清空';
end;

end.







另一篇文章,未整理
每一个节点下子节点形成这一节点的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表示节点被选中时图片序号。

???reeview1.Items.AddChildObject(node1, 'child', nil);

















相关文档
最新文档