delphi中TreeView控件使用
- 格式:doc
- 大小:55.00 KB
- 文档页数:15
Delphi中为TreeView添加单选和复选框 打开电脑,进⼊Windows操作系统,在资源管理器的左边栏中清楚地显⽰了系统管理的所有磁盘的信息以及各个磁盘所容纳的⽂件与⽂件夹(如图⼀)。
这种常见的显⽰⽅式是由⼀个根节点和若⼲个⼦节点构成的,这被称为“树形结构”。
这种树形结构的⽤途⾮常⼴泛,在很多常⽤软件中都出现过它的⾝影。
Windows中将这种结构封装为“树形控件”,即TreeView控件,它与ListView、Button等⼀样都属于系统⾃带的通⽤公共控件。
在Delphi中,TreeView也被封装成了VCL组件,它的位置在“Win32组件”⾯板上,是我们最常⽤的⼏个组件之⼀。
Delphi⾃带的TreeView组件可以显⽰树形结构,也可以为每个节点指定不同的图标来区分各⾃的功能。
但在平时的使⽤中,我们发现它并不能嵌⼊CheckBox或者是RadioButton组件,这样⽤户就不能直观地选择某⼀部分节点或某个节点。
如何来解决这个问题呢?我们思考之后发现,有两种思路可以完成前⾯所述的任务。
⼀种是在TreeView组件的基础上继承的它的功能,并添加所要的功能(使TreeView能嵌⼊CheckBox或者是RadioButton组件)即重写⼀个组件。
另⼀种是利⽤⽤户的错觉,将CheckBox或者是RadioButton所能实现的外观⽤两种状态的图⽚(⼀种是选中状态另⼀种是未选中状态)来交替显⽰,⾛迂回路线来完成任务。
我们来分析⼀下这两种⽅法的优缺点:第⼀种⽅法要重写⼀个组件,显然难度较⼤,所⽤时间较长;第⼆种⽅法,利⽤TreeView组件本⾝就具备的显⽰图标功能,简便易⾏,所⽤时间短,能够完成需求。
⽐较之后,我们选择作⽤第⼆种⽅法,先来看⼀下完成之后的效果(如图⼆),应该说是达到了⽬的,现在我们来细述⼀下完成的过程: ⾸先,我们在Win32⾯板上选择ImageList组件,设置它的StateImages属性,包括两种状态的图标,⼀种是选中状态,另⼀种是未先中状态。
DelPhi Treeview 操作实例onclick节点treeview1.Selected.Level2011-08-31 15:58怎么改变Treeview中的图标? OnClick事件Click获取Node.text 批量处理及实现TreeView结点拖拽的实例//这个过程根据你的要求选择图标procedure TForm1.TreeView1GetImageIndex(Sender: TObject; Node: TTreeNode);beginif Node.HasChildren thenif Node.Expanded thenNode.ImageIndex := 3 //节点有子节点时打开的图标elseNode.ImageIndex := 0 //节点有子节点时收起来的图标else Node.ImageIndex := 1; //节点没有子节点时图标end;//这个过程显示选择的图标procedure TForm1.TreeView1GetSelectedIndex(Sender: TObject; Node: TTreeNode);beginNode.SelectedIndex := Node.ImageIndex; //节点选择后使用的图标end;——————————————————————————————————-//treeview的单击事件procedure TForm1.TreeView1Click(Sender: TObject);begin//如果选中节点的等级(level)为0(根节点等级为0,根节点的子节点等级为1,依次类推)并且其序号(index)为0(同等级下的的节点按从上到下数第一个为0,第二个为1,以此类推)if(treeview1.Selected.Level = 0)and(treeview1.Selected.Index = 0) thenbegin//这里写点中了第一个根节点后要做的事form1.Color := clred;endelseif (treeview1.Selected.Level = 1)and(treeview1.Selected.Index=1) thenbegin//这里写点中了第三个根节点的第2个子节点后要做的事form1.Color := clblue;end;end;//如果你想点节点前的“+”号也有同样的效果,那么就应该在Expanding事件里写判断处理程序。
一:TreeView.Items[0].Expanded:=True;//展开第一个节点二:TreeView.Items[0].Item[0].Selected:=True;//移动到第一个节点的第一个子节点找当前节点的下一个节点,按序号找如下:if treeview1.Selected.GetNext<>nil thentreeview1.Selected.GetNext.Selected:=true;TreeView1.SetFocus;找当前节点的下一个同层兄弟如下:if treeview1.Selected.getNextSibling<>nil thentreeview1.Selected.getNextSibling.Selected:=true;TreeView1.SetFocus;TreeView.Selected.getPrevSibling//当前选中节点的上一个兄弟节点TreeView.Selected.Parent//当前选中节点的父节点getfirstchild是跳到该节点子结点中的第一个getlastchild是跳到该节点子结点中的最后一个如果你是想跳到同层兄弟结点的第一个if treeview1.selected.parent<>nil thentreeview1.selected.parent.getfirstchild.selected:=trueelsetreeview1.items.item[0].selected:=true;如果你是想跳到同层兄弟结点的最后一个if treeview1.selected.parent<>nil thentreeview1.selected.parent.getlastchild.selected:=trueelsetreeview1.Items.Item[treeview1.Items.Count-1].Selected:=true;TreeView的使用方法基本信息:TreeView是一个显示树型结构的控件,每一个节点都是一个新类,使用具有代表性每个节点都有四个值:TEXT:显示文字Image Index:显示图形序号Selected Index:State Index:(1)建立目录项(本例中使用的TREEVIEW名称为:TvwTips)增加根目录下的节点:(节点)varCatNode:TTreeNode;//先建立一个TREEVIEW使用的子对象beginTvwTips.SetFocus;//将焦点置到这个TREEVIEW控件上{在根标题下建立一个新的子标题}CatNode:=TvwTips.Items.AddChild(TvwTips.Items.GetFirstNode,'New Category');CatNode.ImageIndex:=1;CatNode.SelectedIndex:=2;CatNode.EditText;{允许用户改变这个标题}end;增加下一级目录(内容):varParentNode,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,'NewSubject',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的第一个节点,函数类型为:TTreeNodeTvwTips.Items.Count返回当前TreeView的全部节点数,整数TvwTips.Selected.Level返回当前选中节点的在目录树中的级别,根目录为0TvwTips.Selected.Parent返回当前选中节点上级节点,函数类型为:TTreeNode三、下面这段程序是用TREEVIEW连数据库及一些操作:unit bmzd;usesWindows,Messages,SysUtils,Classes,Graphics,Controls,Forms,Dialogs, StdCtrls,ComCtrls,Db,DBTables,ImgList,Buttons,ExtCtrls,Grids, DBGrids;typeTfrmbmzd=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;varfrmbmzd:Tfrmbmzd;ii:integer;tv:ttreenode;constSCodeFormat='222222';//科目代码结构SFirstNodeTxt='部门分类';implementationuses dm;{$R*.DFM}function tfrmbmzd.LoadCode(crTbl:TDBDataSet):Integer; var NowID,sName,ShowTxt:String;i,Level:Integer;MyNode:array[0..6]of TTreeNode;//保存各级节点,最长支持6级(重点)beginScreen.Cursor:=crHourGlass;Level:=0;With frmdm.tabbm dobegintryif 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 dobeginNowID:=Trim(FieldByName('bumeng_id').AsString); ShowTxt:=FieldByName('bumeng_name').AsString; Level:=GetLevel(SCodeFormat,NowID);//返回代码的级数//以下是增加子项//以下用上一级节点为父节点添加子节点if Level>0then//确保代码符合标准beginMyNode[Level]:=tvwCode.Items.AddChild(MyNode[Level-1],NowID+''+ShowTxt);MyNode[Level].ImageIndex:=1;MyNode[Level].SelectedIndex:=2;end;//以上是增加子项Next;end;finallyClose;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;beginLevel:=-1;//如果代码不符合标准,则返回-1iLen:=0;if(sFormat<>'')and(sCode<>'')thenfor i:=1to Length(sFormat)doiLen:=iLen+StrToInt(sFormat[i]);if Length(sCode)=iLen thenbeginLevel:=i;Break;end;end;Result:=Level;end;procedure Tfrmbmzd.FormShow(Sender:TObject);beginif 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); beginAction:=caFree;end;procedure Tfrmbmzd.cmd_newClick(Sender:TObject);tvwcode.SetFocus;if tvwcode.selected.AbsoluteIndex<>0thenbegincmd_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 thenbeginif tvwcode.Selected.GetLastChild.index+1>9thenedit2.text:=inttostr(tvwcode.Selected.GetLastChild.index+1) elseedit2.text:='0'+inttostr(tvwcode.Selected.GetLastChild.index+1); edit3.text:='新建部门';edit2.Enabled:=true;edit3.Enabled:=true;endelsebeginedit2.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);varI:integer;seno,setext:string;beginif tvwcode.Selected.HasChildren=true thenbeginapplication.messagebox('该部门包含下级,不能删除','提示',MB_OKCANCEL+mb_iconquestion);endelsebeginif application.messagebox('你确实要删除当前部门吗','提示',MB_OKCANCEL+mb_iconquestion)=IDOKbeginsetext:=tvwcode.selected.text;i:=0;while setext[i]<>''dobeginI:=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 thenbeginfrmdm.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); beginif key in['0'..'9',Chr(vk_Back)]thenbeginkey:=#0;application.messagebox('','',mb_ok);end;end;procedure wcodeChange(Sender:TObject;Node:TTreeNode); vari,lev:integer;strr,seno,setext:string;beginif cmd_new.Enabled=true thenbeginif tvwcode.selected.AbsoluteIndex<>0thenbegincmd_delete.Enabled:=true;cmd_update.Enabled:=true;cmd_save.Enabled:=true;setext:=tvwcode.selected.text;i:=0;while setext[i]<>''dobeginI:=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 of2: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);endelsebeginedit1.text:='';edit2.text:='';edit3.text:='部门分类';cmd_delete.Enabled:=false;cmd_update.Enabled:=false;end;end;end;procedure Tfrmbmzd.cmd_updateClick(Sender:TObject);vari:integer;beginfor i:=0to ComponentCount-1dobeginif(Components[I]is tedit)then(Components[I]as tedit).enabled:=false;end;for i:=0to ComponentCount-1dobeginif(Components[I]is tbitbtn)then(Components[I]as tbitbtn).enabled:=true;end;if tvwcode.Selected.AbsoluteIndex<>0thenbeginif 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;tryfrmdm.tabbm.Post;//表的保存excepton edbengineerror dobeginedit2.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);begincmd_new.Enabled:=false;cmd_delete.Enabled:=false;edit2.enabled:=true;edit3.Enabled:=true;end;procedure wcodeClick(Sender:TObject);vari:integer;beginif cmd_new.Enabled=false thenbeginapplication.MessageBox('当前是修改状态,请单击保存按钮','提示',mb_ok); tv.Selected:=true;end;if tvwcode.selected.AbsoluteIndex=0thenbeginfor i:=0to ComponentCount-1dobeginif(Components[I]is tedit)then(Components[I]as tedit).enabled:=false;end;for i:=0to ComponentCount-1dobeginif(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控件使用教程11. TreeView 控件TreeView 控件显示Node 对象的分层列表,每个Node 对象均由一个标签和一个可选的位图组成。
TreeView 一般用于显示文档标题、索引入口、磁盘上的文件和目录、或能被有效地分层显示的其它种类信息。
语法Treeview说明创建了TreeView 控件之后,可以通过设置属性与调用方法对各Node 对象进行操作,这些操作包括添加、删除、对齐和其它操作。
可以编程展开与折回Node 对象来显示或隐藏所有子节点。
Collapse、Expand 和NodeClick 三个事件也提供编程功能。
Node 对象使用Root、Parent、Child、FirstSibling、Next、Previous 和LastSibling 属性。
在代码中可通过检索对Node 对象的引用,从而在树上定位。
也可以使用键盘定位。
UP ARROW 键和DOWN ARROW 键向下循环穿过所有展开的Node 对象。
从左到右、从上到下地选择Node 对象。
若在树的底部,选择便跳回树的顶部,必要时滚动窗口。
RIGHT ARROW 键和LEFT ARROW 键也穿过所有展开的Node 对象,但是如果选择了未展开的Node之后再按RIGHT ARROW 键,该Node 便展开;第二次按该键,选择将移向下一个Node。
相反,若扩展的Node 有焦点,这时再按LEFT ARROW 键,该Node 便折回。
如果按下ANSI 字符集中的键,焦点将跳转至以那个字母开头的最近的Node。
后续的按该键的动作将使选择向下循环,穿过以那个字母开头的所有展开节点。
控件的外观有八种可用的替换样式,它们是文本、位图、直线和+/- 号的组合,Node 对象可以任一种组合出现。
TreeView 控件使用由ImageList 属性指定的ImageList 控件,来存储显示于Node 对象的位图和图标。
任何时刻,TreeView 控件只能使用一个ImageList。
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(),就可以访问所有的节点。
四、建树举例:varroot_node,cur_node:TTreeNode;beginroot_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,即当前被选中的节点。
treeview用法Treeview一种用于展示数据层次的可视化控件,它通常被用来展示文件夹的内容、文件树状结构、网站的导航结构等。
它可以使用鼠标点击来展开和收起,它的数据通常以树的形式呈现,它可以使用来递归展示数据,以及实现展开和收起的效果。
Treeview使用步骤是:1. 入 Treeview件首先,我们需要在项目中引入 Treeview件,一般来讲,我们可以使用 JavaScript、jQuery、bootstrap相关库来引入 Treeview。
2. 建数据源在使用 Treeview件之前,我们需要准备一份用于展示的文件树状结构的数据。
常见的数据源有 JavaScript数组、JSON式的数据格式等。
3. 始化 Treeview件接着,我们将 Treeview件初始化,通常我们需要指定数据源,以及一些属性,比如支持展开收起等。
4. 建 Treeview 事件当我们在使用 Treeview件的时候,可以创建一些事件,比如点击事件等,这样我们就可以在点击 Treeview件的任意节点时做出相应的反应。
总的来说,Treeview 为我们提供了一种实现文件树状结构展示的可视化控件。
它可以为我们呈现出简洁清晰的数据层次结构,它可以帮助我们更方便地使用它来构建文件层次结构。
Treeview 也可以用于其他更多的场景,比如用于网站的导航设计。
简单的设计可以让用户快速地找到所需的内容,而复杂的设计则可以实现对访问量的控制,帮助用户快速地找到有用的内容。
另外,通过 Treeview件,我们可以让用户看到更直观、更清晰的网站结构,从而使用户可以更加顺利地浏览网站。
另外,Treeview件还可以用于实现较大数据量的展示。
针对于较大的数据量,我们可以利用 Treeview层级展示,实现较大数据量的展示,同时又保留了数据的层次结构,使用户可以更加顺利地浏览数据。
Treeview一种使用极为广泛的可视化控件,它可以用于文件树状结构的展示、网站的导航设计、较大数据量的展示等,它的使用与实现相比较简单,使用它来可视化展示数据是一种更加有效的方式。
delphi中TreeView使⽤常见问题编程⼼得1,在Delphi中,TreeView控件是⼀款很出⾊⽽且很常⽤的控件。
在使⽤过程中,了解到其TTreeNode对象的data属性存储相关数据很有⽤,⼀般情况下,我们先声明⼀个结构体以及其指针,例如:typePMyRc = ^TMyRc;TMyRc = Recordid:string;name:string;age:integer;end;添加⼀个节点,显⽰信息为TMyRc的name,同时存储id,age。
⽅法如下:varp:PMyRc;i:integer;beginRandomize;for i:= 0 to 9 dobeginNew(p);p.id:=inttostr(random(100));:='name'+ inttostr(random(205));p.age:=random(90);// Caption := p.id+' '+ + ' '+inttostr(p.age);TreeView1.Items.AddObject(nil,,Tobject(p));//dispose(p); 如果在这⾥释放指针,id,age并不能存在树中,⽽是在这⾥就被释放了。
应该在释放树的事件⾥书写。
end;end;释放树的事件deletion,即使是删除也会执⾏这些代码。
所以不⽤担⼼内存泄漏。
但是如果不书写以下代码,或者⽤相关的⽅式释放内存,必定会造成内存泄漏。
procedure TForm1.TreeView1Deletion(Sender: TObject; Node: TTreeNode);begindispose(pmyrc(node.data));end;访问某个树枝中的age值:Pmyrc(TreeView1.Selected.data)^.age。
TreeView控件百科名片TreeView控件用来显示信息的分级视图,如同Windows里的资源管理器的目录。
TreeVie w控件中的各项信息都有一个与之相关的Node对象。
TreeView显示Node对象的分层目录结构,每个Node对象均由一个Label对象和其相关的位图组成。
在建立TreeView控件后,我们可以展开和折叠、显示或隐藏其中的节点。
TreeView控件一般用来显示文件和目录结构、文档中的类层次、索引中的层次和其他具有分层目录结构的信息。
目录[隐藏]概述属性方法常用属性常用方法常用事件简单示例[编辑本段]概述TreeView 控件显示Node 对象的分层列表,每个Node 对象均由一个标签和一个可选的位图组成。
TreeView 一般用于显示文档标题、索引入口、磁盘上的文件和目录、或能被有效地分层显示的其它种类信息。
创建了TreeView 控件之后,可以通过设置属性与调用方法对各Node 对象进行操作,这些操作包括添加、删除、对齐和其它操作。
可以编程展开与折回Node 对象来显示或隐藏所有子节点。
Colla pse、Expand 和NodeClick 三个事件也提供编程功能。
Node 对象使用Root、Pa rent、Child、FirstSibling、Next、Previous 和LastSibling 属性。
在代码中可通过检索对Node 对象的引用,从而在树上定位。
也可以使用键盘定位。
UP ARROW 键和DOWN ARROW 键向下循环穿过所有展开的Node 对象。
从左到右、从上到下地选择Node 对象。
若在树的底部,选择便跳回树的顶部,必要时滚动窗口。
RI GHT ARROW 键和LEFT ARROW 键也穿过所有展开的Node 对象,但是如果选择了未展开的Node之后再按RIGHT ARROW 键,该Node 便展开;第二次按该键,选择将移向下一个Node。
相反,若扩展的Node 有焦点,这时再按LEFT A RROW 键,该Node 便折回。
delphi中Treeview的使用介绍每一个节点下子节点形成这一节点的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 的用法开始(挺全的)//************* TreeView 的用法开始******************//一:TreeView.Items[0].Expanded := True; // 展开第一个节点二:TreeView.Items[0].Item[0].Selected := True; // 移动到第一个节点的第一个子节点找当前节点的下一个节点,按序号找如下:if treeview1.Selected.GetNext<>nil thentreeview1.Selected.GetNext.Selected:=true;TreeView1.SetFocus;找当前节点的下一个同层兄弟如下:if treeview1.Selected.getNextSibling<>nil thentreeview1.Selected.getNextSibling.Selected:=true;TreeView1.SetFocus;TreeView.Selected.getPrevSibling //当前选中节点的上一个兄弟节点TreeView.Selected.Parent // 当前选中节点的父节点getfirstchild是跳到该节点子结点中的第一个getlastchild是跳到该节点子结点中的最后一个如果你是想跳到同层兄弟结点的第一个if treeview1.selected.parent<>nil thentreeview1.selected.parent.getfirstchild.selected:=trueelsetreeview1.items.item[0].selected:=true;如果你是想跳到同层兄弟结点的最后一个if treeview1.selected.parent<>nil thentreeview1.selected.parent.getlastchild.selected:=trueelsetreeview1.Items.Item[treeview1.Items.Count-1].Selected:=true;TreeView的使用方法基本信息:TreeView 是一个显示树型结构的控件,每一个节点都是一个新类,使用具有代表性每个节点都有四个值:TEXT:显示文字 Image Index:显示图形序号Selected Index:State Index:(1)建立目录项(本例中使用的TREEVIEW名称为:TvwTips)增加根目录下的节点:(节点)varCatNode : TTreeNode; //先建立一个TREEVIEW使用的子对象beginTvwTips.SetFocus; //将焦点置到这个TREEVIEW控件上{ 在根标题下建立一个新的子标题 }CatNode := TvwTips.Items.AddChild(TvwTips.Items.GetFirstNode,'New Category' );CatNode.ImageIndex := 1;CatNode.SelectedIndex := 2;CatNode.EditText; { 允许用户改变这个标题 }end; 增加下一级目录(内容):varParentNode, TipNode : TTreeNode; //先建立TREEVIEW使用的子对象VersionNum : Integer;beginTvwTips.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的第一个节点,函数类型为:TTreeNodeTvwTips.Items.Count 返回当前TreeView的全部节点数,整数TvwTips.Selected.Level 返回当前选中节点的在目录树中的级别,根目录为0TvwTips.Selected.Parent 返回当前选中节点上级节点,函数类型为:TTreeNode三、下面这段程序是用TREEVIEW连数据库及一些操作:unit bmzd;interfaceusesWindows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ComCtrls, Db, DBTables, ImgList, Buttons, ExtCtrls, Grids,DBGrids;typeTfrmbmzd = 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: TLabelLabel5: 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;varfrmbmzd: Tfrmbmzd;ii:integer;tv:ttreenode;constSCodeFormat = '222222'; //科目代码结构SFirstNodeTxt = '部门分类';implementationuses dm;{$R *.DFM}function tfrmbmzd.LoadCode(crTbl:TDBDataSet):Integer;var NowID,sName,ShowTxt:String;i,Level:Integer;MyNode:array[0..6]of TTreeNode;//保存各级节点,最长支持6级(重点)beginScreen.Cursor:=crHourGlass;Level:=0;With frmdm.tabbm dobegintryif 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 dobeginNowID:=Trim(FieldByName('bumeng_id').AsString); ShowTxt:=FieldByName('bumeng_name').AsString; Level:=GetLevel(SCodeFormat,NowID);//返回代码的级数//以下是增加子项//以下用上一级节点为父节点添加子节点if Level>0 then//确保代码符合标准beginMyNode[Level]:=tvwCode.Items.AddChild (MyNode[Level-1],NowID+' '+ShowTxt);MyNode[Level].ImageIndex:=1;MyNode[Level].SelectedIndex:=2;end; //以上是增加子项Next;end;finallyClose;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;beginLevel:=-1;//如果代码不符合标准,则返回-1iLen:=0;if (sFormat<>'')and(sCode<>'')thenfor i:=1 to Length(sFormat) dobeginiLen:=iLen+StrToInt(sFormat[i]);if Length(sCode)=iLen thenbeginLevel:=i;Break;end;end;Result:=Level;end;procedure Tfrmbmzd.FormShow(Sender: TObject);beginif 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); beginAction := caFree;end;procedure Tfrmbmzd.cmd_newClick(Sender: TObject);begintvwcode.SetFocus ;if tvwcode.selected.AbsoluteIndex<>0 thenbegincmd_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 thenbeginif tvwcode.Selected.GetLastChild.index+1>9 thenedit2.text:=inttostr(tvwcode.Selected.GetLastChild.index+1)elseedit2.text:='0'+inttostr(tvwcode.Selected.GetLastChild.index+1);edit3.text:='新建部门';edit2.Enabled:=true;edit3.Enabled:=true;endelsebeginedit2.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); varI:integer;seno,setext:string;beginif tvwcode.Selected.HasChildren=true thenbeginapplication.messagebox('该部门包含下级,不能删除','提示',MB_OKCANCEL+mb_iconquestion ) ;endelsebeginif application.messagebox('你确实要删除当前部门吗','提示',MB_OKCANCEL+mb_iconquestion )=IDOK thenbeginsetext:=tvwcode.selected.text;i:=0;while setext[i] <> ' ' dobeginI := 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 thenbeginfrmdm.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); beginif key in ['0'..'9',Chr(vk_Back)] thenelsebeginkey:=#0;application.messagebox('','',mb_ok);end;end;procedure wcodeChange(Sender: TObject; Node: TTreeNode);vari,lev:integer ;strr,seno,setext:string;beginif cmd_new.Enabled =true thenbeginif tvwcode.selected.AbsoluteIndex<>0 thenbegincmd_delete.Enabled:=true;cmd_update.Enabled:=true;cmd_save.Enabled :=true;setext:=tvwcode.selected.text;i:=0;while setext[i] <> ' ' dobeginI := 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 of2: 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 );endbeginedit1.text :='';edit2.text :='';edit3.text :='部门分类';cmd_delete.Enabled :=false;cmd_update.Enabled :=false;end;end;end;procedure Tfrmbmzd.cmd_updateClick(Sender: TObject); vari:integer;beginfor i:=0 to ComponentCount-1 dobeginif (Components[I] is tedit ) then(Components[I] as tedit).enabled:=false;end;for i:=0 to ComponentCount-1 dobeginif (Components[I] is tbitbtn ) then(Components[I] as tbitbtn).enabled:=true;end;if tvwcode.Selected.AbsoluteIndex<>0 thenbeginif 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;tryfrmdm.tabbm.Post;//表的保存excepton edbengineerror doedit2.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);begincmd_new.Enabled :=false;cmd_delete.Enabled :=false;edit2.enabled:=true;edit3.Enabled :=true;end;procedure wcodeClick(Sender: TObject);vari:integer;beginif cmd_new.Enabled =false thenbeginapplication.MessageBox('当前是修改状态,请单击保存按钮','提示',mb_ok);tv.Selected :=true;end;if tvwcode.selected.AbsoluteIndex=0 thenbeginfor i:=0 to ComponentCount-1 dobeginif (Components[I] is tedit ) then(Components[I] as tedit).enabled:=false;end;for i:=0 to ComponentCount-1 dobeginif (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控件。
VirtualTreeview使用说明很好用的一个列表控件,可以用来代替Delphi自带的ListView和TreeView,而且也一直在更新,目前已经支持最新的XE2官方网站:SVN地址:/svn/trunk基本的使用方法就不多说了,可以看看Demo,或者百度一下还是有些教程的。
我这里只记录一些属性方法等,方便查阅【属性】EditDelay = 单元格编辑响应时间HintAnimation = Hint动画效果HintMode = Hint显示方式LineMode = 网格线条模式LineStyle = 网格线条样式Header > AutoSizeIndex = 自适应宽度的列索引Header > Options > hoAutoResize = 列自适应宽度开关Header > Options > hoColumnResize = 是否可以自由调整列宽Header > Options > hoDblClickResize = 双击分界线自动改变列度Header > Options > hoDrag = 是否支持拖拽移动Header > Options > hoHotTrack = 高亮显示当前列Header > Options > hoHeightResize = 是否可以自由调整列高TreeOptions > AutoOptions > toAutoExpand = 单击展开节点并收起其他节点TreeOptions > AutoOptions > toAutoTristateTracking = 三态复选框自适应选择,即子节点被选择后父节点Check状态改变TreeOptions > MiscOptions > toCheckSupport = 是否显示复选框。
还需要设置节点的CheckType属性TreeOptions > MiscOptions > toEditable = 是否允许单击编辑单元格TreeOptions > MiscOptions > toFullRepaintOnResize = 控件大小改变时刷新显示数据TreeOptions > MiscOptions > toToggleOnDblClick = 双击展开节点TreeOptions > PaintOptions > toHideSelection = 隐藏选择焦点TreeOptions > PaintOptions > toHotTrack = 当前行是否显示下划线TreeOptions > PaintOptions > toShowDropmark = 拖拽时是否显示插入标记TreeOptions > PaintOptions > toShowRoot = 是否显示父节点展开按钮TreeOptions > PaintOptions > toShowHorzGridLines = 水平网格线开关TreeOptions > PaintOptions > toShowTreeLines = 父节点与子节点的连接线TreeOptions > PaintOptions > toShowVertGridLines = 垂直网格线开关TreeOptions > PaintOptions > toThemeAware = 应用系统主题TreeOptions > PaintOptions > toAlwaysHideSelection = 总是隐藏选择TreeOptions > PaintOptions > toChildrenAbove = 父节点处于子节点下方TreeOptions > SelectionOptions > toDisableDrawSelection = 框选开关TreeOptions > SelectionOptions > toExtendedFocus = 是否允许Cloumn>0的单元格有焦点(有焦点的时候才能编辑)TreeOptions > SelectionOptions > toFullRowSelect = 整行选择TreeOptions > SelectionOptions > toMultiSelect = 是否可以多选TreeOptions > SelectionOptions > toRightClickSelect = 右键是否可以选择TreeOptions > SelectionOptions > toSimpleDrawSelection = 框选时只要该行处于框内即可被选择TreeOptions > StringOptions > toShowStaticText = 是否显示静态文本(在节点正文后面显示的字符,静态文本不能编辑)【方法】TopNode = 设置列表顶部的节点,可以用来定位节点行ScrollIntoView = 设置滚动条位置,可以用来定位节点行【事件】OnChange = 焦点改变时OnCreateEditor = 设置某单元格的编辑框样式,比如TEdit,TComboBox等等。
[编程]DELPHI--TreeView与数据库的使用//写一个过程procedure Tf_Serch.DrawTree;vari: Integer;Nodeo: TTreeNode;begin//打开一个表with dm.qTempQ dobeginClose;SQL.Clear;SQL.Add('select * from t_class order by 编号');Open;end;//打开第二个表with dm.qKid dobeginClose;SQL.Clear;SQL.Add('select * from t_kid order by 班级编号');Open;end;//清空列表RzTreeView1.Items.Clear;//如果第一个表有数据if not dm.qTempQ.Eof thenbegin//设置列表自动打开RzTreeView1.AutoExpand := true;//设置列表为只读RzTreeView1.ReadOnly := true;//增加一个节点,来源是第一个表的合计数和第二个表的合计数 Nodeo := RzTreeView1.Items.AddFirst(nil, '班级数['+ IntToStr(dm.qTempQ.RecordCount) + '个' + IntToStr(dm.qKid.RecordCount) + '人]'); //以第一个表的记录个数进行循环增加子节点for i := 0 to dm.qTempQ.RecordCount - 1 dobegin//打开第三个表,与第二个表相同with dm.qTemp1 dobeginClose;SQL.Clear;SQL.Add('select * from t_kid');Open;//不同的是,这个表过滤数据Filtered := false;Filter := '班级编号 = ' + QuotedStr(dm.qTempQ.FieldByName('编号').AsString);Filtered := true;end;//增加子节点,来源是第一个表某字段的记录和第三个表的合计数RzTreeView1.Items.AddChild(Nodeo, '[' + IntToStr(dm.qTemp1.RecordCount) + '人]'+ dm.qTempQ.FieldByName('名称').Asstring);//第一个表的下一条dm.qTempQ.Next;end;end;if RzTreeView1.Enabled then RzTreeView1.SetFocus;end;//CLICK事件procedure Tf_Serch.RzTreeView1Click(Sender: TObject);varStrPos: string;intPos: Integer;begin//如果列表没有节点则退出if RzTreeView1.Items.GetFirstNode = nil then Exit;//以选择节点的变量判断使用什么表,这个是已知第一个节点的变量是何值,对其进行判断,如果节点则调用一个表后并退出if Pos('班级数', RzTreeView1.Selected.Text) <> 0 thenbegindm.qTempQ.Close;dm.qTempQ.SQL.Clear;dm.qTempQ.SQL.LoadFromFile('bin\selclass.sql');dm.qTempQ.SQL.Add('group by 姓名');dm.qTempQ.Open;with dm.qMTT dobeginClose;SQL.Clear;SQL.LoadFromFile('bin\selIO.sql');SQL.Add('group by 姓名');Open;end;Exit;end;//得到选择的节点的变量StrPos := RzTreeView1.Selected.Text;//对变量进行判断intPos := pos(']',StrPos);//获得一个变量StrPos := Copy(StrPos, intPos+1, Length(StrPos)-intPos);//依上个变量值调用表灵气with dm.qTemp2 dobeginClose;SQL.Clear;SQL.Add('select * from t_class where 名称=''' + StrPos + '''');Open;StrPos := fieldbyname('编号').AsString;end;//上面的调用是两表主键的使用,与treeview无关,调用出的数据在dbgrid中显示 with dm.qTempQ dobeginClose;SQL.Clear;SQL.LoadFromFile('bin\selclass.sql');SQL.Add('where 班级编号=''' + StrPos + '''');SQL.Add(' and 时间>=:d1 and 时间<=:d2');SQL.Add(' group by 姓名');Parameters.ParamByName('d1').Value := RzDateTimeEdit1.Date;Parameters.ParamByName('d2').Value := RzDateTimeEdit2.Date + 1;Open;end;with dm.qMTT dobeginClose;SQL.Clear;SQL.LoadFromFile('bin\selIO.sql');SQL.Add('where 班级编号=''' + StrPos + '''');sql.add(' and 日期时间>=''' + RzDateTimeEdit1.text + '''');sql.add(' and 日期时间<=''' + RzDateTimeEdit2.text + '''');SQL.Add(' group by 姓名');Open;end;end;。
浅谈Delphi⾼效使⽤TreeView本来我⼀直都是使⽤递归算法, 效率很低下边这段代码是我原来写的-----------------------------------------------------------------------------------------------------procedure TForm1.GetDepartmentMsg;varTest, Test2 : TTreeNode;procedure NodeAdd(Test : TTreeNode; DepartmentId : string);varTestlevel : TTreeNode;TestQuery : TADOQuery;begintryTestQuery := TADOQuery.Create(Nil);TestQuery.Connection := ADOConnection1;With TestQuery dobeginClose;SQL.Text := 'Select DepartmentID ,NAME from Department where DepartmentID like '''+DepartmentId+'%'' and Len(DepartmentId) = ' + IntToStr(Length (DepartmentId) + 2) + 'Group by DepartmentID ,name order by DepartmentID ' ;Open;if Not IsEmpty thenbeginwhile not Eof dobeginTestlevel := TreeView1.Items.AddChild(Test,TestQuery.fieldbyName('Name').AsString + ' | '+TestQuery.fieldbyName('DepartmentId').AsString);NodeAdd(Testlevel,TestQuery.fieldbyName('DepartmentId').AsString);Testlevel.ImageIndex := Testlevel.Level -1;Testlevel.SelectedIndex := Testlevel.Level -1;Next;end;end;end;finallyTestQuery.free;end;end;beginTest := TreeView1.Items.Add(nil,' ***** | 00');Test.ImageIndex := 1;with Query1 dobeginClose;Sql.Text := 'Select * from Department where State = ''正常'' and DepartmentLevel = ''1'' ';Open;end;Query1.First;TreeView1.Items.BeginUpdate;while not Query1.Eof dobeginTest2 := TreeView1.Items.AddChild(Test,Query1.fieldbyName('Name').AsString + ' | '+ Query1.fieldbyName('DepartmentId').AsString) ; NodeAdd(Test2,Query1.fieldbyName('DepartmentId').AsString);Query1.Next;end;TreeView1.Items.EndUpdate;Query1.Close;end;今天⽆事测试了这段代码时间是6-7秒左右下边这段改进后的,不使⽤递归procedure TForm1.NewGetDepartmentMsg;constDivNum = 2;varnLevel: Integer;pNodes: array[0..1023] of TTreeNode;DepartmentID, Name: string;Str: string;beginStr := 'Select DepartmentID, Name from Department order by DepartmentID';with adoquery1 dobeginClose;Sql.clear;Sql.add(Str);Open;end;TreeView1.Items.Clear;TreeView1.Items.BeginUpdate;pNodes[0] := TreeView1.Items.Add(nil, '***');if Not ADOQuery1.IsEmpty thenwhile not ADOQuery1.Eof dobeginDepartmentID := ADOQuery1.fieldbyName('DepartmentID').AsString;Name := ADOQuery1.fieldbyName('Name').AsString;nLevel := Length(DepartmentID) div DivNum ;pNodes[nLevel] := TreeView1.Items.AddChild(pNodes[nLevel - 1], DepartmentID + ' | ' + Name);ADOQuery1.Next;end;TreeView1.Items.EndUpdate;ADOQuery1.Close;end;这个算法主要合理利⽤了 'Select DepartmentID, Name from Department order by DepartmentID' 来排序, 这就保证了pNodes[nLevel] := TreeView1.Items.AddChild(pNodes[nLevel - 1], DepartmentID + ' | ' + Name);他的上级结点不为空这段代码我⼀测试, ⼤概是0.2秒左右, 数据和上边那段代码处理⼀样的数据这样写肯定是有缺陷的, 也不是什么情况下都能使⽤写得不对的地⽅,欢迎批评和指正,谢谢。
DELPHI中利用TreeView控件建立目录树2000-06-26 00:00:00· -·中国计算机报社p>Rainbow的话:关于TreeView的使用,还可以参看:联合使用TreeView 组件TreeView是一个显示树型结构的控件,通过它能够方便地管理和显示具有层次结构的信息,是Windows应用程序的基本控件之一。
DELPHI 虽然具有比较强大的文件管理功能,提供了多个用于文件管理的标准控件,如DriveComboBox、DirectoryListBox、FileListBox等,通过设置它们的属性,使其建立起联系,甚至不用编写一行程序,我们就可以实现在不同的目录之间进行切换,然而这样的目录切换只适用于进行文件的查找定位,而不能方便地进行目录的浏览,例如我们要从c:\windows 目录转到c:\program files目录,就必须返回到根目录才能进行切换,而不能象Windows资源管理器那样任意地在不同的目录之间进行浏览与切换。
要实现在不同目录之间任意切换和浏览,还是需要使用TreeView控件,以下程序就利用DELPHI的TreeView控件来建立目录树。
在该程序中采用的各部件以及界面设计如下图所示:各部件的主要属性设置如下:部件属性属性值form namecaptionform1‘目录浏览’drivecommbobox namevisibledrivecommbobox1falsefilelistbox namevisiblefiletypefilelistbox1falsefddirectoryimagelist name imagelist1treeview name images该程序利用DriveCommboBox控件来获得系统具有的驱动器,并以此作为目录树的最上层,利用FileListBox控件,通过设置其Filetype属性为fdDirectory,可以获得所需的子目录,在TreeView控件的OnExpanding事件中将得到的子目录加到该控件的某一节点下。
treeview控件用法TreeView控件是一种类似于目录树的控件,用于显示层次结构的数据。
它通常用来显示文件和文件夹的层次关系,也可以用来显示任何具有层次结构的数据。
使用TreeView控件的一般步骤如下:1. 在窗体中放置一个TreeView控件。
2. 使用Nodes属性添加根节点和子节点。
3. 为每个节点设置Text属性,用来显示节点的文本。
4. 可以设置节点的ImageIndex属性和SelectedImageIndex属性,来显示节点的图标。
5. 使用父节点的Nodes属性来添加子节点,形成层次结构。
6. 可以为节点添加事件处理程序,以便响应节点的单击、双击等操作。
以下是一个简单的例子,演示如何使用TreeView控件:```c#// 创建根节点TreeNode rootNode = new TreeNode("根节点");// 创建子节点TreeNode childNode1 = new TreeNode("子节点1");TreeNode childNode2 = new TreeNode("子节点2");TreeNode childNode3 = new TreeNode("子节点3");// 将子节点添加到根节点rootNode.Nodes.Add(childNode1);rootNode.Nodes.Add(childNode2);rootNode.Nodes.Add(childNode3);// 将根节点添加到TreeView控件treeView1.Nodes.Add(rootNode);```这样就创建了一个简单的TreeView控件,其中包含一个根节点和三个子节点。
TreeView控件使用教程11、TreeView 控件TreeView 控件显示Node 对象的分层列表,每个Node 对象均由一个标签与一个可选的位图组成。
TreeView 一般用于显示文档标题、索引入口、磁盘上的文件与目录、或能被有效地分层显示的其它种类信息。
语法Treeview说明创建了TreeView 控件之后,可以通过设置属性与调用方法对各Node 对象进行操作,这些操作包括添加、删除、对齐与其它操作。
可以编程展开与折回Node 对象来显示或隐藏所有子节点。
Collapse、Expand 与NodeClick 三个事件也提供编程功能。
Node 对象使用Root、Parent、Child、FirstSibling、Next、Previous 与LastSibling 属性。
在代码中可通过检索对Node 对象的引用,从而在树上定位。
也可以使用键盘定位。
UP ARROW 键与DOWN ARROW 键向下循环穿过所有展开的Node 对象。
从左到右、从上到下地选择Node 对象。
若在树的底部,选择便跳回树的顶部,必要时滚动窗口。
RIGHT ARROW 键与LEFT ARROW 键也穿过所有展开的Node 对象,但就是如果选择了未展开的Node之后再按RIGHT ARROW 键,该Node 便展开;第二次按该键,选择将移向下一个Node。
相反,若扩展的Node 有焦点,这时再按LEFT ARROW 键,该Node 便折回。
如果按下ANSI 字符集中的键,焦点将跳转至以那个字母开头的最近的Node。
后续的按该键的动作将使选择向下循环,穿过以那个字母开头的所有展开节点。
控件的外观有八种可用的替换样式,它们就是文本、位图、直线与+/- 号的组合,Node 对象可以任一种组合出现。
TreeView 控件使用由ImageList 属性指定的ImageList 控件,来存储显示于Node 对象的位图与图标。
treeview控件用法(一)TreeView控件用法详解1. 概述TreeView控件是一种常用的用户界面控件,常用于显示层次结构的数据。
它通常用于文件资源管理器、目录结构显示等场景中。
下面详细介绍TreeView控件的一些常见用法和功能。
2. 树状结构显示•树状结构:TreeView控件以树状结构的方式来显示数据,每个节点可以有多个子节点,形成层次结构。
•节点展开和折叠:用户可以通过点击节点前的加号(+)或减号(-)图标,展开或折叠节点的子节点。
•树节点图标:每个树节点都可以设置一个图标显示在节点前面,用于表示不同类型的节点。
3. 构建树•添加根节点:通过调用TreeView控件的()方法,可以在Treeview的根节点下添加子节点。
•添加子节点:通过设置节点的Nodes属性,添加子节点到指定的父节点。
4. 节点操作•插入节点:使用()方法可以在指定位置上插入一个新节点。
•删除节点:使用()方法可以删除指定节点,同时会删除节点的所有子节点。
•修改节点:通过修改节点的Text属性,可以修改节点的文本内容。
5. 节点选择和展示•选择节点:通过设置TreeView控件的SelectedNode属性,可以选中指定的节点。
•展示节点:可以通过设置节点的EnsureVisible属性,使指定节点可见(自动滚动到可见状态)。
6. 节点事件•节点点击事件:可以通过绑定TreeView控件的NodeMouseClick事件,实现对节点的点击响应。
•节点展开折叠事件:通过绑定TreeView控件的BeforeExpand 和BeforeCollapse事件,实现对节点展开和折叠的响应。
7. 其他功能•勾选框:可以通过设置节点的CheckBoxes属性为true,启用节点的勾选框功能。
•拖拽操作:可以通过设置TreeView控件的AllowDrop属性为true,实现节点的拖拽和放置操作。
8. 总结TreeView控件是一种非常实用的界面控件,它提供了树状结构的显示方式,并提供了丰富的操作和事件,能够满足复杂的层次结构数据展示需求。
delphi中TTreeView的使⽤⽅法【学习万⼀⽼师博客摘要】TTreeView 与两个重要的类相关:TTreeNodes、TTreeNode 。
TTreeNodes即是TTreeView 的Items属性,TTreeNodes是TTreeNode的合集,TTreeNode代表的是TTreeView的节点,不按主从关系,节点依次存储在Items中。
TTreeView的Select⽅法⽤来指定TTreeView选择的节点,可以选择多个节点。
TTreeNodes使⽤add添加同级节点,使⽤addChild添加下级节点。
node.parent表⽰node节点的上级节点。
TTreeNode的⼀些属性:'绝对序号':Node.AbsoluteIndex'所在级别':Node.Level'在兄弟中排⾏':Node.Index'下级总数':Node.Count'上级元素':Node.Parent.text'上⼀个':Node.GetPrev.text'下⼀个':Node.GetNext.text'上⼀个兄弟':Node.GetPrevSibling.text'下⼀个兄弟':Node.GetNextSibling.text'上⼀个可见':Node.GetPrevVisible.text'下⼀个可见':Node.GetNextVisilbe.text'第⼀个下级':Node.GetFirstChild.text'最后⼀个下级':Node.GetLastChile.text'总数':Node.Ower.countTreeView的items属性可以导出为*.txt⽂件,并可从⽂件或流中导⼊,需要注意流或⽂件中的数据格式有严格要求, 要求必须是树状结构; 结构中可以⽤"空格"和"Tab"分层.treeview的插⼊、删除操作{插⼊, 只能通过 TTreeNodes}node := TreeView1.Selected;TreeView1.Items.Insert(node, '新成员');{⽤ TTreeNodes 删除}node := TreeView1.Selected;TreeView1.Items.Delete(node);{⽤TTreeNode删除}node := TreeView1.Selected;node.Delete;{删除它的所有下级}node := TreeView1.Selected;if node.HasChildren thennode.DeleteChildren。
Delphi7中Treeview控件的应用
向隅
【期刊名称】《武汉船舶职业技术学院学报》
【年(卷),期】2008(007)001
【摘要】Treeview控件用于显示树型结构的数据,通常用来显示比较复杂的信息.本文介绍了dell3hi7中treeview树型控件的属性、节点对象的添加和获取方法,重点介绍了用treeview控件显示数据库信息的实现.
【总页数】3页(P18-20)
【作者】向隅
【作者单位】武汉铁路职业技术学院电子信息工程系,湖北武汉,430063
【正文语种】中文
【中图分类】TP311
【相关文献】
1.ODBC数据源在Delphi7数据库中自动管理的应用 [J], 高永峰;付芳
2.基于Delphi7多线程技术在网络中的应用研究 [J], 刘冬;靳蓓蓓
3.Delphi7中ADO组件在无线电子封签系统中的应用 [J], 曹建加;陈伟
4.TreeView控件在C#应用程序中的应用研究 [J], 邹治军
5.TreeView控件在C#应用程序中的应用研究 [J], 邹治军
因版权原因,仅展示原文概要,查看原文内容请购买。
DELPHI中利用TreeView控件建立目录树2000-06-26 00:00:00·-·中国计算机报社p>Rainbow的话:关于TreeView的使用,还可以参看:联合使用TreeView 组件TreeView是一个显示树型结构的控件,通过它能够方便地管理和显示具有层次结构的信息,是Windows应用程序的基本控件之一。
DELPHI虽然具有比较强大的文件管理功能,提供了多个用于文件管理的标准控件,如DriveComboBox、DirectoryListBox、FileListBox等,通过设置它们的属性,使其建立起联系,甚至不用编写一行程序,我们就可以实现在不同的目录之间进行切换,然而这样的目录切换只适用于进行文件的查找定位,而不能方便地进行目录的浏览,例如我们要从c:\windows目录转到c:\program files目录,就必须返回到根目录才能进行切换,而不能象Windows资源管理器那样任意地在不同的目录之间进行浏览与切换。
要实现在不同目录之间任意切换和浏览,还是需要使用TreeView控件,以下程序就利用DELPHI的TreeView控件来建立目录树。
在该程序中采用的各部件以及界面设计如下图所示:各部件的主要属性设置如下:部件属性属性值form namecaptionform1 ‘目录浏览’drivecommbobox name visible drivecommbobox1 falsefilelistbox name visible filetype filelistbox1 false fddirectoryimagelist name imagelist1treeview name images该程序利用DriveCommboBox控件来获得系统具有的驱动器,并以此作为目录树的最上层,利用FileListBox控件,通过设置其Filetype属性为fdDirectory,可以获得所需的子目录,在TreeView控件的OnExpanding事件中将得到的子目录加到该控件的某一节点下。
整个程序的源代码如下:unit main;interfaceuses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,StdCtrls, FileCtrl, ComCtrls, ImgList;typeTForm1 = class(TForm)DirTreeView: TTreeView;FileListBox1: TFileListBox;DriveComboBox1: TDriveComboBox;ImageList1: TImageList;procedure FormCreate(Sender: TObject);procedure DirTreeViewExpanding(Sender: TObject; Node: TTreeNode;var AllowExpansion: Boolean);private{ Private declarations }public{ Public declarations }end;varForm1: TForm1;implementation{$R *.DFM}procedure (Sender: TObject);varFirstNode,DirNode : TTreeNode;ItemCount,Index:integer;Itemstr:string;beginItemCount:= and (itemstr 〈〉 ..) thenbeginDirNode := );:=true;:= 0;:= 1;icount:=icount+1;end;if icount = 0 then:= false;end;end;end;end.程序的运行效果如图所示:我们可以展开目录树中的任何一个节点,并且可以在任意节点之间切换,就象我们在Windows资源管理器中所作的那样,而不需要逐级回退之后才能进行切换。
•••••••••Delphi中根据分类数据生成树形结构的最优方法很多系统都有类似于如下的表结构(table1):ID Name ParentID---------------------------------------------------------001 电子类0002 金属类 0003 电容电子 001004 电阻电子 001005 有色金属002而且大家都习惯于用树(TreeView)来显示,这样就可以很好的显示整个表的分类情况。
但如果数据量多时会造成树的生成比较慢,特别是用递归来实现时要访问数据库的次数很多(根据层数),用在三层中效果更加显。
在此提供一个好的方法来生成树形结构。
这个算法只访问一次数据库,具体的实现如下:1、一次性从数据库中取出所有的数据,并按照ParentID字段进行排序,这样就保证每一条数据的父节点都在它的前面。
2、取出第一条数据画到树中,在添加到树中时先找到这条数据的父节点,如果没有则将此记录直接作为树的第一级节点3、如果还有数据,则取出来执行第2步,直到没有数据为止。
程序实现:本程序将用一个stlID的TStringList变量来存放对应树中每一个节点的ID值,用FindParent函数来父节点。
function FindParent(ID:String):TTreeNode;vari:Integer;beginresult:=nil;for i:= downto 0 doif [i]=ID thenbeginresult:=[i];break;end;end;sString),('Name').AsString);('ID').AsString);如何初始化一个TreeView?弄一个窗口,放上一个TreeView和一个Button,分别取名为TV1和Btn1。
如果需要在每个节点前有个图,请在窗口上放上一个ImageList,取名为ImageList1,双击它,加入六个图标。
还要记得记得将TV1的Images属性改为ImageList1噢。
双击按钮Btn1,在里面填入以下代码,然后按F9运行,点击Btn1就可以看到效果了。
procedure (Sender: TObject);ConstMyDocDir = 'C:\My Documents';PersonDir = '3hSoft';VarI : Word;SubNodeName : array [1..5] of ShortString; RootNode, SubNode : TTreeNode;P : PString;beginSubNodeName[1] := '便笺';SubNodeName[2] := '发件箱';SubNodeName[3] := '联系人';SubNodeName[4] := '任务';SubNodeName[5] := '日记';New(P);P^ := MyDocDir + '\' + PersonDir;RootNode := '个人文件夹', P);TreeView中如何设置选中结点vari:integer; {i为设置的选中结点的索引值}beginif i> then[i].selected:=true;或:=[i];三。
设置TreeView结点的图形1. 设置TreeView的images属性为已存在的images对象:=imagelist1;2. 在加入结点后执行:varanode:TTreeNode;begeinanode:=(nil,'item1');:=0; {结点未选中时显示的图标}:=1; {结点选中时显示的图标}end3. 如果结点图形在改变后未发生变化,可以执行:;四。
如何批量处理TreeView结点使用TreeView的items属性的BeginUpdate和EndUpdate方法,例:for i:=0 to dobeginfile :ext:=lowercase[i].text);end;五。
实现TreeView结点拖拽的实例下面的程序片段演示了如何实现拖拽treeview构件结点的例子{鼠标按下时执行的语句}procedure (Sender: TObject;Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin{判断左键按下并且鼠标点在一个结点上开始实现拖拽}if ( Button = mbLeft ) and( htOnItem in ( X, Y ) ) thenbegin( False );end;end;{鼠标拖动执行语句}procedure ( Sender, Source: TObject;X, Y: Integer; State: TDragState; var Accept: Boolean);varNode : TTreeNode;beginif Source = Treeview1 thenbeginNode := ( X, Y ); {取当前结点}if Node <> nil then {当前结点不为空才能实现拖拽,accept:=true}Accept := true;end;end;{鼠标释放时执行的语句}procedure ( Sender, Source: TObject;X, Y : Integer );varTempNode : TTreeNode;AttachMode : TNodeAttachMode;beginif = nil thenExit;AttachMode := naAddChild; {设置结点移动模式,设移动结点为子结点}{ 注意在这里存在一个bug,当移动结点时,如果目标结点没有子结点,}{ 则加入的新的子结点会失败,所以先在当前目标结点的下面 }{ 加入一个临时子结点,移动完毕后,再将临时结点删除 }tryTempNode := ,'Temp' );try{ 移动选中的结点到目标结点 }, AttachMode );finally; { 不要忘了释放临时结点 }end;finallyend;end;今天上午到现在的心得想从以下的一段代码来说明。
代码很简单(当我搞完后才觉得简单,搞了半天,哎,没办法,资质有限呀),主要是要完成当双击TreeView中的一项的时候将数据库中符合条件的数据显示在一个DBGird中。