delphi中TreeView使用与一些应用

TreeView由节点构成,建树通过对TreeView.items属性进行操作。Items是一个TTreeNodes对象,这是一个TTreeNode集。

一、针对TTreeNodes,也就是 TreeView.Items,有这些属性:

1、count,节点个数。

2、item[index] ,通过index得到节点。

二、针对TTreeNodes,也就是 TreeView.Items,常用的添加节点的操作有:

AddFirst添加第一个根节点。由此函数添加的节点总排在前面,除非后来又使用此函数添加了一个节点,则后添加的节点将排在前面。该函数返回新添加的节点。

AddChildFirst添加第一个子节点,要求有父节点作为其参数。返回新添加的节点。

AddChild添加一个子节点,要求有父节点作为其参数。返回新添加的节点。

Add添加一个兄弟节点,要求有兄弟节点作为其参数。返回新添加的节点。

三、针对TTreeNodes,也就是 TreeView.Items,常用的得到节点的操作有:

GetFirstNode() 得到根节点。

然后配合TTreeNode.GetNext(),就可以访问所有的节点。

四、建树举例:

var

root_node,cur_node:TTreeNode;

begin

root_node:=AddFirst(nil,根节点1);

cur_node:=addChildfirst(root_node,nil,根节点1_child1);

add(cur_node,根节点1_child2);

root_node:=Add(nil,根节点2);

AddChildFirst(root_node,根节点2_child1);

end;

五、事件触发:

当从一个节点跳到另一个节点,会触发TTreeView.OnChange事件。该事件中,将传递node,即当前被选中的节点。

当修改一个节点的text时,会触发TTreeView.onEdit事件。

六、将节点和节点所对应的数据联系起来

对于每个TTreeNode,有个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

self.label1.caption:=pmyData(node.data)^.Fname+pmyData(node.data)^.Lname

end;

七、一般使用流程:

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中

一. 如何初始化一个TreeView?

弄一个窗口,放上一个TreeView和一个Button,分别取名为TV1和Btn1。如果需要

在每个节点前有个图,请在窗口上放上一个ImageList,取名为ImageList1,双击

它,加入六个图标。还要记得记得将TV1的Images属性改为ImageList1噢。双击按

钮Btn1,在里面填入以下代码,然后按F9运行,点击Btn1就可以看到效果了。

procedure TForm1.Btn1Click(Sender: TObject);

Const

MyDocDir = \'C:\My Documents\';

PersonDir = \'3hSoft\';

Var

Var

I : Word;

SubNodeName : array [1..5] of ShortString;

RootNode, SubNode : TTreeNode;

P : PString;

begin

SubNodeName[1] := \'便笺\';

SubNodeName[2] := \'发件箱\';

SubNodeName[3] := \'联系人\';

SubNodeName[4] := \'任务\';

SubNodeName[5] := \'日记\';

TV1.Items.Clear;

TV1.Items.BeginUpdate;

New(P);

P^ := MyDocDir + \'\\' + PersonDir;

RootNode := TV1.Items.AddObject(Nil, \'个人文件夹\', P);

// 此 Node 的图标已对 Images 属性中取第 0 个了。

For I := 1 to 5 do

begin

New(P);

P^ := MyDocDir + \'\\' + PersonDir + \'\\' + SubNodeName[I];

SubNode := TV1.Items.AddChildObject(RootNode, SubNodeName[I], P)

;

;

// 如果不想使用图标的话请删除以下两行

SubNode.ImageIndex := I;

SubNode.SelectedIndex := I;

end;

TV1.Items.EndUpdate;

end;

二.在TreeView中如何设置选中结点

var

i:integer; {i为设置的选中结点的索引值}

begin

if i>treeview1.items.count then

treeview1.items[i].selected:=true;

treeview1.selected:=treeview1.items[i];

三。设置TreeView结点的图形

1. 设置TreeView的images属性为已存在的images对象

treeview1.images:=imagelist1;

2. 在加入结点后执行:

var

anode:TTreeNode;

begein

anode:=Treeview1.add(nil,\'item1\');

anode.imageindex:=0; {结点未选中时显示的图标}

anode.selectedindex:=1; {结点选中时显示的图标}

end

3. 如果结点图形在改变后未发生变化,可以执行:

treeview1.refresh;

四。如何批量处理TreeView结点

使用TreeView的items属性的BeginUpdate和EndUpdate方法,例:

TreeView1.items.BeginUpdate;

for i:=0 to TreeView1.items.count-1 do

begin

file ://将每个结点的文字改成为小写字母

TreeView1.items[i].text:=lowercase(TreeView1.items[i].text);

end;

TreeView1.items.EndUpdate;

五。实现TreeView结点拖拽的实例

下面的程序片段演示了如何实现拖拽treeview构件结点的例子

{鼠标按下时执行的语句}

procedure TForm1.Treeview1MouseDown(Sender: TObject;

Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

begin

{判断左键按下并且鼠标点在一个结点上开始实现拖拽}

if ( Button = mbLeft ) and

( htOnItem in Treeview1.GetHitTestInfoAt( X, Y ) ) then

begin

Treeview1.BeginDrag( False );

end;

end;

{鼠标拖动执行语句}

procedure TForm1.Treeview1DragOver( Sender, Source: TObject;

X, Y: Integer; State: TDragState; var Accept: Boolean);

var

Node : TTreeNode;

begin

if Source = Treeview1 then

begin

Node := Treeview1.GetNodeAt( X, Y ); {取当前结点}

if Node <> nil then {当前结点不为空才能实现拖拽,accept:=true}

Accept := true;

end;

end;

{鼠标释放时执行的语句}

procedure TForm1.Treeview1DragDrop( Sender, Source: TObject;

X, Y : Integer );

var

TempNode : TTreeNode;

AttachMode : TNodeAttachMode;

begin

if Treeview1.Selected = nil then

Exit;

AttachMode := naAddChild; {设置结点移动模式,设移动结点为子结点}

{ 注意在这里存在一个bug,当移动结点时,如果目标结点没有子结点,}

{ 则加入的新的子结点会失败,所以先在当前目标结点的下面 }

{ 加入一个临时子结点,移动完毕后,再将临时结点删除 }

Treeview1.Items.BeginUpdate;

try

TempNode := Treeview1.Items.AddChild( Treeview1.DropTarget,

\'Temp\' );

try

{ 移动选中的结点到目标结点 }

Treeview1.Selected.MoveTo( Treeview1.DropTarget, AttachMode );

finally

TempNode.Free; { 不要忘了释放临时结点 }

end;

finally

Treeview1.Items.EndUpdate;

end;

end;