delphi树控件的用法

delphi树控件的用法
delphi树控件的用法

一:TreeView.Items[0].Expanded := True; // 展开第一个节点

二:TreeView.Items[0].Item[0].Selected := True; // 移动到第一个节点的第一个子节点找当前节点的下一个节点,按序号找如下:

if treeview1.Selected.GetNext<>nil then

treeview1.Selected.GetNext.Selected:=true;

TreeView1.SetFocus;

找当前节点的下一个同层兄弟如下:

if treeview1.Selected.getNextSibling<>nil then

treeview1.Selected.getNextSibling.Selected:=true;

TreeView1.SetFocus;

TreeView.Selected.getPrevSibling //当前选中节点的上一个兄弟节点

TreeView.Selected.Parent // 当前选中节点的父节点

getfirstchild是跳到该节点子结点中的第一个

getlastchild是跳到该节点子结点中的最后一个

如果你是想跳到同层兄弟结点的第一个

if treeview1.selected.parent<>nil then

treeview1.selected.parent.getfirstchild.selected:=true

else

treeview1.items.item[0].selected:=true;

如果你是想跳到同层兄弟结点的最后一个

if treeview1.selected.parent<>nil then

treeview1.selected.parent.getlastchild.selected:=true

else

treeview1.Items.Item[treeview1.Items.Count-1].Selected:=true;

TreeView的使用方法

基本信息:

TreeView 是一个显示树型结构的控件,每一个节点都是一个新类, 使用具有代表性

每个节点都有四个值:

TEXT:显示文字Image Index:显示图形序号

Selected Index:

State Index:

(1)建立目录项(本例中使用的TREEVIEW名称为:TvwTips)

增加根目录下的节点:(节点)

var

CatNode : TTreeNode; //先建立一个TREEVIEW使用的子对象begin

TvwTips.SetFocus; //将焦点置到这个TREEVIEW控件上

{ 在根标题下建立一个新的子标题}

CatNode := TvwTips.Items.AddChild(

TvwTips.Items.GetFirstNode,'New Category' );

CatNode.ImageIndex := 1;

CatNode.SelectedIndex := 2;

CatNode.EditText; { 允许用户改变这个标题}

end;

增加下一级目录(内容):

var

ParentNode, TipNode : TTreeNode; //先建立TREEVIEW使用

的子对象

VersionNum : Integer;

TvwTips.SetFocus; //将焦点置到这个TREEVIEW控件上

VersionNum := TMenuItem( Sender ).Tag; { Ver num of new tip } ParentNode := TvwTips.Selected; { 取出当前的选中节点}

if ParentNode.Level = nlTip then{ Parent cannot be a tip node } ParentNode := TvwTips.Selected.Parent;

TipNode := TvwTips.Items.AddChildObject( ParentNode,'New

Subject',Pointer( VersionNum ) );

TipNode.ImageIndex := 3; { Normal tip bitmap }

TipNode.SelectedIndex := 4; { Highlighted tip bitmap }

TipNode.MakeVisible; { Move new tip node into view }

TipNode.EditText; { Immediately allow user to edit subject } EnableTreeViewFunctions( TipNode.Level );

RtfTip.Clear;

RtfTip.Modified := False;

end;

(2)说明

TvwTips.Items.GetFirstNode 返回TREEVIEW的第一个节点,函数类型为:TTreeNode

TvwTips.Items.Count 返回当前TreeView的全部节点数,整数TvwTips.Selected.Level 返回当前选中节点的在目录树中的级别,

根目录为0

TvwTips.Selected.Parent 返回当前选中节点上级节点,函数类型为

:TTreeNode

三、下面这段程序是用TREEVIEW连数据库及一些操作:

unit bmzd;

uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ComCtrls, Db, DBTables, ImgList, Buttons, ExtCtrls, Grids,

DBGrids;

type

Tfrmbmzd = class(TForm)

Panel1: TPanel;

cmd_new: TBitBtn;

cmd_delete: TBitBtn;

cmd_exit: TBitBtn;

tvwcode: TTreeView;

ScrollBox1: TScrollBox;

GroupBox2: TGroupBox;

Label3: TLabel;

Label2: TLabel;

Label1: TLabel;

Label4: TLabel;

Label5: TLabel;

Edit2: TEdit;

Edit3: TEdit;

Edit4: TEdit;

Edit5: TEdit;

ImageList1: TImageList;

Edit1: TEdit;

cmd_save: TBitBtn;

cmd_update: TBitBtn;

procedure FormShow(Sender: TObject);

procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure cmd_newClick(Sender: TObject);

procedure cmd_deleteClick(Sender: TObject);

procedure Edit2KeyPress(Sender: TObject; var Key: Char);

procedure tvwcodeChange(Sender: TObject; Node: TTreeNode); procedure cmd_updateClick(Sender: TObject);

procedure BitBtn2Click(Sender: TObject);

procedure tvwcodeClick(Sender: TObject);

private

{ Private declarations }

function LoadCode(crTbl:TDBDataSet):Integer;

function GetLevel(sFormat,sCode:String):Integer;

public

{ Public declarations }

end;

var

frmbmzd: Tfrmbmzd;

ii:integer;

tv:ttreenode;

const

SCodeFormat = '222222'; //科目代码结构

SFirstNodeTxt = '部门分类';

implementation

uses dm;

{$R *.DFM}

function tfrmbmzd.LoadCode(crTbl:TDBDataSet):Integer; var NowID,sName,ShowTxt:String;

i,Level:Integer;

MyNode:array[0..6]of TTreeNode;

//保存各级节点,最长支持6级(重点)

begin

Screen.Cursor:=crHourGlass;

Level:=0;

With frmdm.tabbm do

begin

try

if not Active then Open;

First;

tvwCode.Items.Clear;

//以下是增加第一项

MyNode[Level]:=tvwCode.Items.Add

(tvwCode.TopItem,SFirstNodeTxt);

MyNode[Level].ImageIndex:=0;

MyNode[Level].SelectedIndex:=0;

//以上是增加第一项

While Not Eof do

begin

NowID:=Trim(FieldByName('bumeng_id').AsString); ShowTxt:=FieldByName('bumeng_name').AsString; Level:=GetLevel(SCodeFormat,NowID);

//返回代码的级数

//以下是增加子项

//以下用上一级节点为父节点添加子节点

if Level>0 then//确保代码符合标准

begin

MyNode[Level]:=tvwCode.Items.AddChild

(MyNode[Level-1],NowID+' '+ShowTxt);

MyNode[Level].ImageIndex:=1;

MyNode[Level].SelectedIndex:=2;

end;

//以上是增加子项

Next;

end;

finally

Close;

end;

end;

MyNode[0].Expand(False);//将首节点展开

Screen.Cursor:=crDefault;

end;

//以上函数将Code.db表中的科目代码和科目代码名称显示出来

//下面函数的功能是返回一代码的级数,

//参数sFormat传递科目代码结构;

//参数sCode传递某一科目代码

function tfrmbmzd.GetLevel

(sFormat,sCode:String):Integer;

var i,Level,iLen:Integer;

begin

Level:=-1;//如果代码不符合标准,则返回-1

iLen:=0;

if (sFormat<>'')and(sCode<>'')then

for i:=1 to Length(sFormat) do

iLen:=iLen+StrToInt(sFormat[i]);

if Length(sCode)=iLen then

begin

Level:=i;

Break;

end;

end;

Result:=Level;

end;

procedure Tfrmbmzd.FormShow(Sender: TObject);

begin

if not frmdm.tabbm.active then frmdm.tabbm.Open;

frmdm.tabbm.IndexFieldNames:='BUMENG_ID';

//按字段aCode排序(不要漏掉)

LoadCode(frmdm.tabbm);

end;

procedure Tfrmbmzd.FormClose(Sender: TObject; var Action: TCloseAction); begin

Action := caFree;

end;

procedure Tfrmbmzd.cmd_newClick(Sender: TObject);

tvwcode.SetFocus ;

if tvwcode.selected.AbsoluteIndex<>0 then

begin

cmd_delete.Enabled:=true;

cmd_update.Enabled:=true;

cmd_save.Enabled :=true;

if not frmdm.tabbm.Active then frmdm.tabbm.Open;

edit1.text:=frmdm.tabbm.Fields[0].asstring;

end;

tvwcode.SetFocus ;

tvwcode.Items.AddChild(tvwcode.selected,'新建部门');

if tvwcode.Selected.HasChildren then

begin

if tvwcode.Selected.GetLastChild.index+1>9 then

edit2.text:=inttostr(tvwcode.Selected.GetLastChild.index+1)

else

edit2.text:='0'+inttostr(tvwcode.Selected.GetLastChild.index+1); edit3.text:='新建部门';

edit2.Enabled:=true;

edit3.Enabled:=true;

end

else

begin

edit2.text:='01';

edit3.text:='新建部门';

edit2.Enabled:=true;

edit3.Enabled:=true;

end;

if not frmdm.tabbm.Active then frmdm.tabbm.Open;

frmdm.tabbm.edit;

frmdm.tabbm.Append;

cmd_new.Enabled :=false;

cmd_delete.Enabled :=false;

cmd_update.Enabled :=false;

cmd_save.Enabled :=true;

//新建下级部门

tvwcode.Selected.GetLastChild.Selected:=true;

//设选择

tv:=tvwcode.Selected ;

tvwcode.autoExpand:=true;

tvwcode.SetFocus ;

end;

procedure Tfrmbmzd.cmd_deleteClick(Sender: TObject);

var

I:integer;

seno,setext:string;

begin

if tvwcode.Selected.HasChildren=true then

begin

application.messagebox('该部门包含下级,不能删除','提示',MB_OKCANCEL+mb_iconquestion ) ;

end

else

begin

if application.messagebox('你确实要删除当前部门吗','提示',MB_OKCANCEL+mb_iconquestion )=IDOK

begin

setext:=tvwcode.selected.text;

i:=0;

while setext[i] <> ' ' do

begin

I := I + 1;

seno:=seno+setext[i];

end;

if not frmdm.tabbm.Active then frmdm.tabbm.Open;

frmdm.tabbm.setkey;

frmdm.tabbm.Fields[0].asstring:=seno;

if frmdm.tabbm.GotoKey then

begin

frmdm.tabbm.edit;

frmdm.tabbm.Delete;

end;

tvwcode.Selected.Delete ;

cmd_new.Enabled :=true;

tvwcode.autoExpand:=true;

tvwcode.SetFocus ;

end;

end;

end;

procedure Tfrmbmzd.Edit2KeyPress(Sender: TObject; var Key: Char); begin

if key in ['0'..'9',Chr(vk_Back)] then

begin

key:=#0;

application.messagebox('','',mb_ok);

end;

end;

procedure https://www.360docs.net/doc/0b4023793.html,wcodeChange(Sender: TObject; Node: TTreeNode); var

i,lev:integer ;

strr,seno,setext:string;

begin

if cmd_new.Enabled =true then

begin

if tvwcode.selected.AbsoluteIndex<>0 then

begin

cmd_delete.Enabled:=true;

cmd_update.Enabled:=true;

cmd_save.Enabled :=true;

setext:=tvwcode.selected.text;

i:=0;

while setext[i] <> ' ' do

begin

I := I + 1;

seno:=seno+setext[i];

end;

if not frmdm.tabbm.Active then frmdm.tabbm.Open;

frmdm.tabbm.setkey;

frmdm.tabbm.Fields[0].asstring:=seno;

frmdm.tabbm.GotoKey;

strr:='';

case tvwcode.Selected.Level of

2: strr:=copy(frmdm.tabbm.fields[0].asstring,1,2);

3: strr:=copy(frmdm.tabbm.fields[0].asstring,1,4);

end;

edit1.text:=strr;

//加上级编码

edit3.text:=frmdm.tabbm.Fields[1].asstring;

//本级编码

edit2.text:=copy(frmdm.tabbm.fields[0].asstring,length(frmdm.tabbm.fields[0].asstring)-1,2);

end

else

begin

edit1.text :='';

edit2.text :='';

edit3.text :='部门分类';

cmd_delete.Enabled :=false;

cmd_update.Enabled :=false;

end;

end;

end;

procedure Tfrmbmzd.cmd_updateClick(Sender: TObject);

var

i:integer;

begin

for i:=0 to ComponentCount-1 do

begin

if (Components[I] is tedit ) then

(Components[I] as tedit).enabled:=false;

end;

for i:=0 to ComponentCount-1 do

begin

if (Components[I] is tbitbtn ) then

(Components[I] as tbitbtn).enabled:=true;

end;

if tvwcode.Selected.AbsoluteIndex<>0 then

begin

if not frmdm.tabbm.Active then frmdm.tabbm.Open;

frmdm.tabbm.Edit;

frmdm.tabbm.Fields[0].asstring:=edit1.text+edit2.text;

frmdm.tabbm.Fields[1].asstring:=edit3.text;

try

frmdm.tabbm.Post;

//表的保存

except

on edbengineerror do

begin

edit2.Enabled :=true;

application.messagebox('编号不能重复,请重新输入','提示',MB_OK+mb_iconquestion ) ; exit;

end;

end;

tvwcode.Selected.Text:=edit1.text+edit2.text+' '+edit3.text;

tvwcode.SetFocus ;

//修改树

end;

cmd_new.Enabled :=true;

edit2.Enabled :=false;

end;

procedure Tfrmbmzd.BitBtn2Click(Sender: TObject);

begin

cmd_new.Enabled :=false;

cmd_delete.Enabled :=false;

edit2.enabled:=true;

edit3.Enabled :=true;

end;

procedure https://www.360docs.net/doc/0b4023793.html,wcodeClick(Sender: TObject);

var

i:integer;

begin

if cmd_new.Enabled =false then

begin

application.MessageBox('当前是修改状态,请单击保存按钮','提示',mb_ok); tv.Selected :=true;

end;

if tvwcode.selected.AbsoluteIndex=0 then

begin

for i:=0 to ComponentCount-1 do

begin

if (Components[I] is tedit ) then

(Components[I] as tedit).enabled:=false;

end;

for i:=0 to ComponentCount-1 do

begin

if (Components[I] is tbitbtn ) then

(Components[I] as tbitbtn).enabled:=false;

cmd_new.Enabled :=true;

cmd_exit.Enabled :=true;

end;

end;

end;

end

四、使用概述

树形图(Treeview)是Win95下新增加的通用显示部件(Common Control,在COMCTL32.DLL中)之一,从Delphi2.0开始也增加了相应的控件Treeview,用于取代原Outline控件。由于树形图结构较复杂,使用起来常不知如何下手。这里就使用中的一些问题作些介绍。

Treeview用于显示按照树形结构进行组织的数据,这在实际当中用途还是比较广泛的,如计算机中的文件系统(Windows95中的资源管理器)、企业或公司的组成结构等等。Treeview控件中一个树形图由节点(TreeNode)和连接线组成。TtreeNode是TTreeview的基本组成单元。一个树的节点又包含文本(Text)和数据(Data)。Text为String类,Data则为无定形指针(Untyped Pointer),可以指向一个与节点相联系的数据结构。

每一个节点下子节点形成这一节点的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表示节点被选中时图片序号。

3.关于Level

Level的概念可以用下图表示:

Level0Level1 Level2

4.排序

SortType决定什么时候进行排序;

TreeView.AlphaSort对节点进行排序,如果不能满足要求,你可以定义自己的CustomSort方法。

5.Drag&Drop操作,与标准的拖放操作使用方法一样。

五、一个例子:

首先,在库的构建上要有一定策略以下几个字段非常重要:

'codeID' 代码集名称(例如:'AB')

'code' 节点代码(例如:'新疆'节点的代码为'65','乌鲁木齐'的节点代码为'6501'等)

'description' 节点描述(例如:如上面的'新疆'、'乌鲁木齐'等)

'pptr' 父节点代码(例如:'乌鲁木齐'节点的父代码为'65',最高层节点的父节点代码可同其代码集,例如:'新疆'的父节点为 'AB')

'cptr' 子节点标识(例如:该节点是否有下级节点,有则取值'1',没有则取值'0')

建立树由两部分构成:

procedure TForm1.FormActivate(Sender: TObject);

var

code_ID,new_sql,node_text,table_name:string;

new_node:Ttreenode;

begin

//要传递的参数

code_ID:='AB';

table_name:='sr_codeitem';

//********

treeview1.Items.BeginUpdate;

//清空所有项目

treeview1.Items.Clear;

new_sql:='select * from '+ table_name + ' where codeID='+''''+code_ID+'''' + ' and '+'pptr='+''''+code_ID+'''';

//数据集中先筛选出所有要增加节点

with dm1.Query1 do

begin

close;

sql.Clear;

sql.Add(new_sql);

open;

//增加第一层节点

while not eof do

begin

node_text:=fieldbyname('code').asstring;

node_text:=node_text+' '+fieldbyname('description').asstring;

new_node:=treeview1.Items.add(nil,node_text);

new_node.HasChildren:=true;

next;

end;//end while

end;//end with

treeview1.Items.EndUpdate;

end;

procedure TForm1.TreeView1Expanding(Sender: TObject; Node: TTreeNode;

var AllowExpansion: Boolean);

var

new_sql,node_text,child_text,code_ID,table_ID:string;

child_node:Ttreenode;

begin

//获取参数

code_ID:='AB';

table_ID:='sr_codeitem';

treeview1.Items.BeginUpdate;

node_text:=node.Text;

//截取所点击节点的code

node_text:=copy(node_text,1,pos(' ',node_text)-1);

with dm1.Query1 do

begin

close;

sql.Clear;

new_sql:='select * from '+table_ID+' where pptr='+''''+node_text+'''' + ' and codeID=' +''''+code_ID+'''';

sql.Add(new_sql);

相关主题
相关文档
最新文档