[Delphi]TreeView简介
Delphi中为TreeView添加单选和复选框
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 操作实例
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事件里写判断处理程序。
delphi中TreeView控件使用
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事件中将得到的子目录加到该控件的某一节点下。
Delphi中用Xml配置文档生成Treeview
Delphi中⽤Xml配置⽂档⽣成Treeview⽤递归⽅法,使⽤ xml ⽂档⽣成 Treeview 树形视图。
由于是动态⽣成,所以可以通过修改 xml 的逻辑来定制 Treeview 的结构,从⽽实现了 xml 对 Treeview 的动态配置,⽽不⽤修改代码。
xml ⽂件如下:<?xml version="1.0" encoding="gb2312"?><root topic="频道列表" catalog="none"><channel topic="操作系统" catalog="none"><channel topic="Windows频道" catalog="windows" /><channel topic="DOS频道" catalog="dos" /><channel topic="Linux" catalog="linux" /></channel><channel topic="菜鸟专区" catalog="cainiaozhuanqu" /><channel topic="应⽤软件" catalog="app" /><channel topic="安全专区" catalog="safe" /><channel topic="代码实验室" catalog="lab" /><BBS topic="电脑学习社区" catalog="none"><subBBS topic="⼦社区-1" catalog="sub1" /><subBBS topic="⼦社区-2" catalog="sub2" /></BBS></root>程序代码如下:unit tree_xml;interfaceusesWindows, Messages, SysUtils, Variants, Classes, Graphics, Controls,Forms, Dialogs, ComCtrls, StdCtrls, XMLDoc, XMLIntf;typeTForm1 = class(TForm)TreeView1: TTreeView;Memo1: TMemo;Button1: TButton;procedure TreeView1MouseDown(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer);procedure Button1Click(Sender: TObject);privatefunction CreateTreeview(XmlNode: IXMLNode; TreeNode: TTreeNode):TTreeNode;{ Private declarations }public{ Public declarations }end;typepRec = ^TData;TData = recordsCatalog: string;sReserved: Stringend;varForm1: TForm1;implementation{$R *.dfm}function TForm1.CreateTreeview(XmlNode: IXMLNode; TreeNode: TTreeNode): TTreeNode;vari: integer;ParentTreeNode, CurrentTreeNode: TTreeNode;pData: pRec;beginNew(pData);pData^.sCatalog := XmlNode.AttributeNodes['catalog'].NodeValue;CurrentTreeNode := TreeView1.Items.AddChildObject(TreeNode,XmlNode.AttributeNodes['topic'].NodeValue, pData); //pointer(...)if XmlNode.HasChildNodes thenbeginParentTreeNode := CurrentTreeNode;for i:=0 to XmlNode.ChildNodes.Count-1 dobeginCreateTreeview(XmlNode.ChildNodes[i], ParentTreeNode);end;end;result := CurrentTreeNode;end;{------------------------------------------------------------------}procedure TForm1.TreeView1MouseDown(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer);var pData: pRec;beginpData := Treeview1.Selected.Data;Memo1.Lines.Add(pData^.sCatalog);end;procedure TForm1.Button1Click(Sender: TObject);varoXml: TXMLDocument;beginoXml := TXMLDocument.Create(self);oXml.FileName := '_Treeview.xml';oXml.Active:=true;CreateTreeview(oXml.ChildNodes.FindNode('root'), Treeview1.Items.GetFirstNode);Treeview1.FullExpand; //节点全部展开oXml.Free;end;end.注意程序中 Treeview 的 TreeView1.Items.AddChildObject ⽅法,其最后⼀个参数⽤来保存该节点的相关数据,是⼀个指针类型的数据,使⽤时要格外⼩⼼。
《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(),就可以访问所有的节点。
四、建树举例: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,即当前被选中的节点。
delphi TreeView详解
property ChangeDelay: Integer;
Use ChangeDelay to get or set the delay, in milliseconds, between when a node is selected and when the OnChange event occurs.
ValueMeaning
bsNoneNo visible border
bsSingleSingle-line border
Canvas
property Canvas: TCanvas;
Use the Canvas property to paint to the canvas from the OnCustomDraw and OnCustomDrawItem event handlers.
MultiSelectStyle
type
TMultiSelectStyles = (msControlSelect, msShiftSelect, msVisibleOnly, msSiblingOnly);
TMultiSelectStyle = set of TMultiSelectStyles;
MultiSelect
property MultiSelect: Boolean;
Set MultiSelect to specify whether users can select multiple nodes using the Control and Shift keys. A selection style must also be chosen in MultiSelectStyle.
Read DropTarget to determine whether a node in the tree view is drawn as the target of a drag and drop operation. Set DropTarget when specifying a particular node in the tree view as the drop target of a dragged item.
delphi中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。
第八章VCL组件应用续2
第八章 VCL组件应用 (续二)
8.1 树状视图组件(TreeView)
TreeView组件位于组件板的Win32页上,它将 列表内容分级显示,呈树状结构。在树状结构的列 表中有一系列节点和子节点,可以将节点展开或折 叠。 Windows资源管理器窗口中就以树状视图的形 式显示出了系统目录。 TreeView组件最重要的属性是Items属性,它 决定了列表中的内容
下一页
返回
Delphi面向对象程序设计
第八章 VCL组件应用 (续二)
8.2 列表视图组件(ListView)
列表视图组件ListView位于组件板的Win32页 上,与列表框组件ListBox非常相似。不同的是,列 表视图组件可以让用户选择不同的显示方式,如: 大图标方式、小图标方式、列表方式和详细资料方 式等。Windows操作系统的资源管理器的左边是一 个TreeView组件,而右边就是一个典型的ListView 组件。 ListView组件中显示的项目由Items属性来设置, 其显示方式则由ViewStyle属性来确定。
Delphi面向对象 程序设计
主编 李俊平
第八章 VCL组件应用 (续二)
• 本章内容
树状视图组件TreeView 列表视图组件ListView 跟踪条组件TrackBar和进度条组件 ProgressBar Tab组件TabControl和多页面组件 PageControl
Delphi面向对象程序设计
下一页
上一页
返回
Delphi面向对象程序设计
第八章 VCL组件应用 (续二) 8.3 跟踪条组件(TrackBar)和进度条组 件(ProgressBar)
TrackBar组件和ProgressBar组件位于 组件板的Win32页,都可以用来指示一个区 域或范围中的位置,它们有很多相似的属性、 方法和事件,如属性:Max、Min、 Orientation、Positiond等;TrackgressBar最常用 的方法是StepIt和StepBy 。
delphi中Treeview的使用介绍
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的编辑器设置各节点的内容。
[Delphi]VirtualTreeview使用说明
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与数据库的使用
[编程]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
Delphi TreeView1. IntroductionDelphi TreeView is a graphical user interface (GUI) control included in the Delphi programming environment. It allows users to display and manage hierarchical data in a tree-like structure. The tree view control is commonly used to represent folders and files in a file explorer, hierarchical data in an organizational chart, or any other data that has a parent-child relationship. In this document, we will explore the features and usage of the Delphi TreeView control.2. FeaturesThe Delphi TreeView control provides a range of features to enhance the user experience and facilitate the management of hierarchical data. Some of the key features include:2.1. Hierarchical StructureThe TreeView control organizes data in a hierarchical manner. Each item in the tree represents a node, and can have child nodes. This allows for convenient representation of parent-child relationships.2.2. CustomizationTreeView allows developers to customize the appearance and behavior of the tree nodes. Developers can change the font, background color, and icons associated with the nodes. Theycan also define custom actions for mouse clicks or keyboard events.2.3. Node ManipulationTreeView allows users to add, delete, and modify nodes at runtime. This enables dynamic updates to the tree structure based on user actions or data changes. Developers can programmatically manipulate the nodes using methods provided by the TreeView control.2.4. Drag and DropTreeView supports drag and drop operations, allowing users to rearrange nodes within the tree or move nodes between different tree views. These operations can be helpful in organizing data or implementing features like file management.2.5. ImageListTreeView can be associated with an ImageList control, which stores a collection of icons or images. Each node can be assigned an image index from the ImageList, allowing for visual representation of different types of nodes.2.6. Data BindingTreeView supports data binding, allowing developers to populate the tree with data from a data source such as a database. This simplifies the process of displaying and managing large amounts of hierarchical data.3. UsageTo use the Delphi TreeView control in your Delphi application, you need to follow a series of steps. Here is a basic outline of the process:3.1. Adding the TreeView ControlTo add the TreeView control to your Delphi form, simply drag and drop it from the toolbox onto your form. You can resize and position the control as desired.3.2. Adding NodesTo populate the TreeView with nodes, you can use the Items property of the TreeView control. This property provides access to the TTreeNodes object, which representsthe collection of nodes in the TreeView. You can add nodes using the Add method or create a node hierarchy by using the AddChild method.3.3. Customizing NodesYou can customize the nodes by modifying their properties such as Text, ImageIndex, and SelectedIndex. These properties allow you to set the text displayed on the node, associate an image with the node, and specify the image index for selected nodes.3.4. Handling EventsTreeView provides various events that you can handle to respond to user actions or changes in the tree structure. Some commonly used events include OnExpand, OnCollapse, and OnDblClick. These events allow you to perform custom actions when a node is expanded, collapsed, or double-clicked.4. ConclusionThe Delphi TreeView control is a versatile tool for displaying and managing hierarchical data in a Delphi application. It offers a range of features that enable customization, node manipulation, drag and drop operations, and data binding. By leveraging the capabilities of TreeView, developers can create intuitive and user-friendly interfaces for handling hierarchical data.。
浅谈Delphi高效使用TreeView
浅谈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.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>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) 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<>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 )=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<>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);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:=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 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=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控件。
delphi中TreeView控件使用
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事件中将得到的子目录加到该控件的某一节点下。
Delphi树形控件(TreeView)节点间的拖动
Delphi树形控件(TreeView)节点间的拖动Delphi树形控件(TreeView)节点间的拖动 很久没写博客了,因为实在没什么东西可写。
不过,今天以前的同事问我,关于TreeView的操作,那我就顺便写在博客⾥,稍微展开⼀下,说说TreeView吧。
TTreeView是VCL⾥⾯⼀个类,也是我们经常会⽤到的,⽽且功能也是很强⼤的。
与TreeView相关的⼀个极其重要的类就是TTreeNode,我们下⾯的操作,⼏乎都是在围绕着它进⾏的。
下⾯直接切⼊正题,要实现节点间的拖动,都需要实现哪⼏个事件呢?1. ⾸先,要实现 OnMouseDown ,在其内要写⼊开启拖动的代码。
2. 然后,要实现 OnDragOver ,其主要作⽤是在拖动过程中,实现对节点拖动⽬的(di)的控制。
3. 最后,要实现 OnDragDrop ,其是实现拖动释放的操作。
这三个事件,我们可以简单的理解为,拖动开始、拖动过程、拖动结束(虽然“拖动开始”和“拖动结束”都有他们各⾃对应的事件,但是也不妨碍我们这样的理解)。
⾸先是 OnMouseDown 事件。
procedure TfrmMain.TreeView1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);varnode: TTreeNode;beginnode := TreeView1.GetNodeAt(X, Y); // 获取⿏标按下位置的节点if (node <> nil) and (node.Level > 0) and (Button = mbLeft) thenTreeView1.BeginDrag(True); // 启动拖动end; 需要注意的是,TreeView 控件的 DragMode 要设置为 dmManual,才会需要执⾏ BeginDrag ⼿⼯启动拖动。
delphi中TTreeView的使用方法
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。
delphitreeview节点移动函数
delphitreeview节点移动函数//TreeView节点移动函数,支撑同级移动跟任意移动。
up代表移动方向,true上移false下移;//同级移动的时候须要传进选中节点的level,免意挪动level=-1 procedureUpDownNode(node:TTreeNode;up:boolean;level:integer);var TargetNode: TTreeNode;beginif (level<>-1) then //同级间移动beginif (node <>nil)then //检查是否有选中节点如果有则做上移操作beginif (up) then //上移beginif (node.GetPrev <> nil) thenbeginTargetNode := node.GetPrev;while TargetNode.Level <> level dobeginif TargetNode.GetPrev=nil thenbreakelseTargetNode := TargetNode.GetPrev;end;if (TargetNode<>nil) thenbeginif (TargetNode.Level=level) thenbeginif (node.getPrevSibling <> nil) then //检查是否有同级上一节点beginif (node.getPrevSibling <> nil) thennode.MoveTo(TargetNode,naInsert)elsenode.MoveTo(TargetNode,naAddFirst);end elsebeginnode.MoveTo(TargetNode,naAdd);end;end;end;end;end else //下移beginif (node.GetNext <> nil) thenbeginTargetNode := node.getNext;while TargetNode.Level <> level dobeginif TargetNode.GetNext=nil thenbreakelseTargetNode := TargetNode.getNext;end;if (TargetNode<>nil) thenbeginif (TargetNode.Level=level) thenbeginif (node.getNextSibling <> nil) then //检讨是否有同级上一节beginif (TargetNode.getNextSibling <> nil) thennode.MoveTo(TargetNode.getNextSibling,naInsert)elsenode.MoveTo(TargetNode,naAdd);end elsebeginnode.MoveTo(TargetNode,naInsert);end;end;end;end;end;end;end else //容许跨级移动beginif (node <> nil)then //检讨是否有选中节点假如有则做上移操作beginif (up) then //上移beginif (node.GetPrev <> nil) thenbeginTargetNode := node.GetPrev;if (TargetNode<>nil) thenbeginif (node.GetPrev <> nil) then //检查是否有同级上一节点如果有做上移操作beginif (node.GetPrev <> nil) thennode.MoveTo(TargetNode,naInsert)elsenode.MoveTo(TargetNode,naAddFirst);end elsebeginnode.MoveTo(TargetNode,naAdd);end;end;end;end else //下移beginif (node.GetNext <> nil) thenbeginTargetNode := node.GetNext;while TargetNode.Parent = node dobeginif TargetNode.GetNext=nil thenbreakelseTargetNode := TargetNode.getNext;end;if (TargetNode<>nil) thenbeginif (node.GetNext <> nil) then //检讨是否有共级上一节点假如有干上移操息beginif (TargetNode.getNext <> nil) thennode.MoveTo(TargetNode.getNext,naInsert)elsenode.MoveTo(TargetNode,naAdd);end elsebeginnode.MoveTo(TargetNode,naAdd); end;end;end;end;end;end;end;。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
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
bel1.caption:=pmyData(node.data)^.Fname+pmyData(node.data)^.Lname
end;
4.内存释放
procedure TForm1.ListView1Deletion(Sender: TObject; Item: TListItem);
begin
Dispose(Item.Data);
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中
释放Data 中指向的内存空间。
另一篇相关介绍:
每一个节点下子节点形成这一节点的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表示节点被选中时图片序号。