vDelphi中TreeView的使用方法介绍

delphiTreeview的使用介绍                                      

  每一个节点下子节点形成这一节点的Items属性,当前节点有一个唯一的Index(TreeNodeIndex属性),用于说明子节点 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控件,加入几个图 片,分别被Index0,1,…TreeviewImage属性项填入你所加入的ImageList的控件名称。TreeNode ImageIndex表示节点未被选中时(Selected=nil)的图片序号,SelectedIndex表示节点被选中时图片序号。


delphitreeview控件基于节点编号的访问
有时我们需要保存和重建treeview控件,本文提供一种方法,通过以树结构节点的编号访问树结构,该控件主要提供的方法如下:
function GetGlobeNumCode(inNode:TTreeNode):String;
功能:返回当前节点的编号,编号规则见源码内说明。

function LocatOrGenerateNode(inNumCode:String):TTreeNode;
功能:以编号返回节点,假如节点的父节点和它的前继兄弟节点不存在,该方法会创建它们,名称为'Temp',当然假如已经存在,就不执行创建工作。
通过以上两个函数,这样我们就可以不加限制的创建和访问节点。该控件在我以前开发的,现在提供给大家做一个参考,希望能对你有帮助。

源码:
// ***********************************************
//
//
用于实现对TreeView控件的树结构的保存和重建
//
编写该控件主要用于实现对行政文件等具有树的层次结构的对象
//
实现保存和显示
//
节点编号规则:
// + ***** ->1
// + ***** ->1.1
// + ***** ->1.1.1
// + ***** ->1.2
//
作者:Jack
//
最后修改日期:2002-12-24
//
// **********************************************
unit CtrlTree;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ComCtrls;

type
TCtrlTree = class(TTreeView)
private
{ Private declarations }
function GetPosAtBound(inString:String;inStart:Integer):Integer;
function GetTheLastPointPos(inString:String):Integer;
protected
{ Protected declarations }
public
{ Public declarations }
function GetNumInSameLevel(inNode:TTreeNode):Integer;
function GetGlobeNumCode(inNode:TTreeNode):String;
function GetParent(inNumCode:String):TTreeNode;
function LocateNodeInLevel(parNode:TTReeNode;LevelCode:integer):TTReeNode;
published
{ Published declarations }
function LocatOrGenerateNode(inNumCode:String):TTreeNode;
function InsertAsFinalChild(inString:String;inNode:TTreeNode):TTReeNode;
function InsertAsPreviousSibling(inString:String;inNode:TTreeNode):TTReeNode;
end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents('Standard', [TCtrlTree]);
end;

{ TCtrTree }

function TCtrlTree.GetNumInSameLevel(inNode: TTreeNode): integer;
{
功能:产生已存在节点在兄弟节点层中对应的编号,从1起编

入口参数:inCode:TTreeNode节点
返回:同层编号
}
var
i:integer;
tmp:TTreeNode;
begin
i:=0;
tmp:=inNode;
while tmp<>nil do
begin
tmp:=tmp.getPrevSibling;
i:=i+1;
end;
Result:=i;
end;

function TCtrlTree.GetGlobeNumCode(inNode: TTreeNode): string;
{
功能:产生已存在节点对应的全局编号

入口参数:inCode:TTreeNode节点
返回:全局编号
}
var
nocode:string;
tmp:TTreeNode;
begin
tmp:=inNode;
nocode:=IntToStr(GetNumInSameLevel(tmp));
while tmp.Level<>0 do
begin
tmp:=tmp.Parent;
nocode:=inttostr(GetNumInSameLevel(tmp))+'.'+nocode;
end;
Result:=nocode;
end;

function TCtrlTree.LocatOrGenerateNode(inNumCode: String): TTreeNode;
{
功能:根据提供的全局编号进行定位,如路径不全,则创建路径

在定位过程产生的节点的TextTemp
最终返回对应于全局编号的子节点

入口参数:inNumCode:String为全局编号
返回:全局编号对应的字节点
}
var
i,j:Cardinal;
NumInLevel:integer;
tmp:TTreeNode;
par:TTreeNode;
begin
tmp:=nil;
i:=1;
while i<=StrLen(PChar(inNumCode)) do
begin
//
得到下一个点号的开始位
j:=GetPosAtBound(inNumCode,i);
//
得到在兄弟节点中的排行数
NumInLevel:=StrToInt(Copy(inNumCode,i,j-i+1));
//
定位父节点
par:=GetParent(Copy(inNumCode,1,j));
//
得到对应的节点
tmp:=LocateNodeInLevel(par,numInLevel);
i:=j+2;
end;
Result:=tmp;
end;

function TCtrlTree.GetParent(inNumCode: String): TTreeNode;
{
功能:根据提供的全局编号找到对应的父节点

如果是第一层的节点,则父节点为nil
入口参数:inNumCode:String为全局编号

返回:全局编号对应的父节点
}
var
GoStep:integer;
i:integer;
j:integer;
k:integer;
SearChInNode:TTReeNode;
ReturnNode:TTReeNode;
begin
//
是第一层节点,返回nil;
k:=GetTheLastPointPos(inNumCode);
if k=0 then
begin
Result:=nil;
Exit;
end;
//
是第二层或第二层以上节点

i:=1;
SearchInNode:=Items.GetFirstNode;
while i < GetTheLastPointPos(inNumCode) do
begin
j:=GetPosAtBound(inNumCode,i);
GoStep:=StrToInt(Copy(inNumCode,i,j-i+1));
if i=1 then //
在第一层节点中搜索
begin
ReturnNode:=SearchInNode;
for k:=1 to GoStep-1 do
ReturnNode:=ReturnNode.getNextSibling;
end
else //
在第二层或第二层以上节点中搜索
begin
GoStep:=StrToInt(Copy(inNumCode,i,j-i+1));
ReturnNode:=SearchInNode.Item[GoStep-1];
end;
SearchInNode:=ReturnNode;
i:=j+2
end;
Result:=SearchInNode;
end;

function TCtrlTree.LocateNodeInLevel(parNode: TTReeNode;LevelCode: integer): TTReeNode;
{
功能:根据父节点以及在兄弟节点中的编号找到对应的节点

如果要创建兄弟及自己,则新创建的节点的TextTemp
入口参数:parNode: TTReeNode为父节点

LevelCode: integer
为编号
返回:在parNode中编号为LevelCode的孩子节点
}
var
i:integer;
j:integer;
tmp:TTreeNode;
tmps:TTreeNode;
begin
//
父节点为空,是第一层节点
tmp:=nil;
if parNode=nil then
begin
i:=1;
tmps:=Items.GetFirstNode;
while (tmps<>nil) and (i<=LevelCode) do
begin
tmp:=tmps;
tmps:=tmps.getNextSibling;
i:=i+1;
end;
i:=i-1;
for j:=1 to LevelCode-i do
tmp:=Items.AddChild(nil,'Temp');
Result:=tmp;
end
else //
父节点不为空,正常处理
begin
if parNode.Count for i:= 1 to LevelCode-parNode.Count do
Items.AddChild(parNode,'Temp');
Result:=parNode.Item[LevelCode-1];
end;
end;

function TCtrlTree.GetPosAtBound(inString: String;inStart:Integer): Integer;
{
功能:根据起始位置找到下一个'.'的前一个位置

入口参数:inString: String节点编号
inStart: Integer
当前处理层次的起始位置
返回:当前处理层次的结束位置
}
var
tmp:Char;
pos:integer;
begin
pos:=inStart+1;
while pos <= Integer(StrLen(PChar(inString))) do
begin
tmp:=inString[pos];
if tmp='.' then
Break
else
pos:=pos+1;
end;
Result:=pos-1;
end;

function TCtrlTree.GetTheLastPointPos(inString: String): Integer;
{
功能:找到编号中最后的'.'的位置

入口参数:inString: String为节点编号
返回:节点编号中最后的'.'的位置
}
var
tmp:Char;
pos:integer;
begin
pos:=Integer(StrLen(PChar(inString)));
while pos>=1 do
begin
tmp:=inString[pos];
if tmp='.' then
Break
else
pos:=pos-1;
end;
Result:=pos;
end;

function TCtrlTree.InsertAsFinalChild(inString: String; inNode: TTreeNode):TTReeNode;
{
功能:为当前节点插入一个孩子节点,位置为最后

入口参数:inString: String为节点编号为待插入节点的字符串
inNode: TTreeNode
,当前节点
}
begin
Result:=Items.AddChild(inNode,inString);
end;

function TCtrlTree.InsertAsPreviousSibling(inString: String;
inNode: TTreeNode):TTReeNode;
{
功能:为当前节点插入一个前导的兄弟节点

入口参数:inString: String为节点编号为待插入节点的字符串
inNode: TTreeNode
,当前节点
}
begin
Result:=Items.AddChildFirst(inNode,inString);end;end.


delphitreeview图标


if TreeView.Items[i].parent = nil then
begin
TreeView.Items[i].ImageIndex := 0;
end;
if TreeView.Items[i].Text = '
退出' then
begin
TreeView.Items[i].ImageIndex := 3;
end;

通过这种方式,设几种图标都行



Delphi 6 IDE中,最显眼的新功能可能就是Object TreeView了。由于Delphi 6比较新,介绍它的资料还很少,所以很多人不知道如何使用Object TreeView,甚至嫌它太占地方而将它关闭了。事实上,当窗体上的构件越来越多的时候,你才会发现Object TreeView的强大功能。

以下是关于Object TreeView功能的一个简单介绍,其主要内容取自《Mastering Delphi 6》,我只是做一些整理和翻译的工作罢了。希望能对使用Delphi 6的朋友有所帮助。

关于Object TreeView的使用

1.在Delphi 5Data Module设计器中,使用了一个TreeView来显示非可视构件(如DataSet, Fields,Actions等等)之间的关系。Delphi 6中的Object TreeView则是它的扩展,它不仅对于Data Module,对于普通窗体和其他对象也可用。

如果Object TreeView当前不可见,而又想使用它,选择View | Object TreeView即可。

2Object TreeView使用层次视图来显示窗体上的构件以及它们之间的关系。最典型的是父子关系:例如,所有Form上的构件都是Form的子节点;又如,放一 Panel到窗体上,再往Panel上面放一个Button,则Button会成为Panel的子节点。

Object TreeViewObject Inspector和窗体设计器是同步的。这就是说,在窗体上选择一个构件,则在Object TreeView中也会自动选中该构件,同时Object Inspector中显示该构件的属性和事件;同理,在Object TreeView中选择一个构件,窗体上也会同时选择该构件,在Object Inspector中显示其属性和事件。因此,Object Inspector可以看作窗体设计器的一个增强,在窗体上构件比较多,而且彼此覆盖的时候,在Object Inspector种选择一个构件往往比从窗体上面选择或者从Object Inspector的列表中查找要方便快捷。

3Object TreeView中还能够显示构件之间的其他关系。举例如下:

1)用Menu Designer设计菜单,所有菜单项按其在菜单中的层次显示在MainMenu节点下;

2)对于数据集构件,例如TTableObject TreeView还会显示它在运行时刻将产生的一些对象,例如SessionAlias等,但由于它们是运行时刻才产生的,所以无法编辑它们的属性,在 Object TreeView中这些对象将以无名称的节点和一个特殊的图标来表示,并且在选中这些节点的时候,Object Inspector中没有属性可以编辑。

3)对于ListViewObject TreeView还会列出它的Columns,在Columns上面点击右键,就可以直接编辑各个列。这比从Form Designer上面选择ListView,再选择Columns Editor来的方便。其他一些构件也有类似的情况,例如HeaderControlSectionsCoolBarBands StatusBarPanels,都可以从快捷菜单中直接编辑。(ToolBar默认情况下虽然没有将Buttons列出,但是仍然可以在从 Object TreeViewToolBar的快捷菜单中建立ButtonSeparator。)

4.想精确设置构件之间的Contains关系,Object TreeView也是一个有用的工具。可以通过下面的试验来验证:

1)在窗体上面放置一个Panel

2)从构件面板上选择Button构件;

3)将鼠标定位在Object TreeView上面(但先不要按下)。你会注意到,当鼠标指向可以作为Container的构件,例如FormPanel的时候,光标形状会变成一个 箭头带一页纸的形状,这说明构件可以放置到Container上面。相反,如果鼠标停留在ListBoxLabel这样的构件上面,那么光标将会变成 No Drop形状,说明它们不能作为Container

4)将光标定位在Panel上面,并按下左键。Button将自动成为Panel的子节点,同时,PanelButton也建立起了contains关系。

你可以很容易的改变构件之间的Contains关系。例如,在Object TreeView中拖动ButtonForm上面,则现在拥有ButtonContainer就不再是Panel,而是Form本身了。在过去,这种 操作是通过Cut&Paste来完成的,但是Cut&Paste也有一个缺点,那就是一个构件被剪切后,它和其他构件之间的关联就丢失 了。而使用Object TreeView,不会有这种缺点。

在窗体上面的构件很多,并且彼此覆盖的时候,在Form Designer中查找和操作某个构件就变得相当麻烦。在这个时候,Object TreeView更能够显示它的作用。

Object TreeViewCode Editor中的Diagram视图配合,还能够发挥更为强大的作用。不过这些内容相当多,需要另外用一个专题来讲述了。   

Object TreeView很有用,不过代价是要多占一点屏幕空间。由于Delphi IDE支持各个工具的Docking,你可以将Object TreeViewObject Inpector组合在一起,成为一个窗口,这样可以稍稍节省一点屏幕空间。Object TreeViewObject Inspector既可以左右排列,也可以上下排列,这两种方式各有优缺点。你可以选择你喜欢的方式,然后用Desktop工具栏上Save Desktop按钮,来将你的桌面设置保存起来供下次使用。

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值