有时我们需要保存和重建treeview控件,本文提供一种方法,通过以树结构节点的编号访问树结构,该控件主要提供的方法如下: function GetGlobeNumCode(inNode:TTreeNode):String; 功能:返回当前节点的编号,编号规则见源码内说明。 function LocatOrGenerateNode(inNumCode:String):TTreeNode; 功能:以编号返回节点,假如节点的父节点和它的前继兄弟节点不存在,该方法会创建它们,名称为''''Temp'''',当然假如已经存在,就不执行创建工作。 通过以上两个函数,这样我们就可以不加限制的创建和访问节点。该控件在我以前开发的,现在提供给大家做一个参考,希望能对你有帮助。
源码: // *********************************************** // // 用于实现对TreeView控件的树结构的保存和重建 // 编写该控件主要用于实现对行政文件等具有树的层次结构的对象 // 实现保存和显示 // 节点编号规则: // + ***** ->1 // + ***** ->1.1 // + ***** ->1.1.1 // + ***** ->1.2 // 作者:Jack // 最后修改日期:2002-12-24 // // ********************************************** unit CtrlTree;
interface
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls;
type TCtrlTree = class(TTreeView) private { Private declarations } function GetPosAtBound(inString:String;inStart:Integer):Integer; function GetTheLastPointPos(inString:String):Integer; protected { Protected declarations } public { Public declarations } function GetNumInSameLevel(inNode:TTreeNode):Integer; function GetGlobeNumCode(inNode:TTreeNode):String; function GetParent(inNumCode:String):TTreeNode; function LocateNodeInLevel(parNode:TTReeNode;LevelCode:integer):TTReeNode; published { Published declarations } function LocatOrGenerateNode(inNumCode:String):TTreeNode; function InsertAsFinalChild(inString:String;inNode:TTreeNode):TTReeNode; function InsertAsPreviousSibling(inString:String;inNode:TTreeNode):TTReeNode; end;
procedure Register;
implementation
procedure Register; begin RegisterComponents(''''Standard'''', [TCtrlTree]); end;
{ TCtrTree }
function TCtrlTree.GetNumInSameLevel(inNode: TTreeNode): integer; {功能:产生已存在节点在兄弟节点层中对应的编号,从1起编 入口参数:inCode:TTreeNode节点 返回:同层编号 } var i:integer; tmp:TTreeNode; begin i:=0; tmp:=inNode; while tmp<>nil do begin tmp:=tmp.getPrevSibling; i:=i+1; end; Result:=i; end;
function TCtrlTree.GetGlobeNumCode(inNode: TTreeNode): string; {功能:产生已存在节点对应的全局编号 入口参数:inCode:TTreeNode节点 返回:全局编号 } var nocode:string; tmp:TTreeNode; begin tmp:=inNode; nocode:=IntToStr(GetNumInSameLevel(tmp)); while tmp.Level<>0 do begin tmp:=tmp.Parent; nocode:=inttostr(GetNumInSameLevel(tmp))+''''.''''+nocode; end; Result:=nocode; end;
function TCtrlTree.LocatOrGenerateNode(inNumCode: String): TTreeNode; {功能:根据提供的全局编号进行定位,如路径不全,则创建路径 在定位过程产生的节点的Text为Temp 最终返回对应于全局编号的子节点 入口参数:inNumCode:String为全局编号 返回:全局编号对应的字节点 } var i,j:Cardinal; NumInLevel:integer; tmp:TTreeNode; par:TTreeNode; begin tmp:=nil; i:=1; while i<=StrLen(PChar(inNumCode)) do begin //得到下一个点号的开始位 j:=GetPosAtBound(inNumCode,i); //得到在兄弟节点中的排行数 NumInLevel:=StrToInt(Copy(inNumCode,i,j-i+1)); //定位父节点 par:=GetParent(Copy(inNumCode,1,j)); //得到对应的节点 tmp:=LocateNodeInLevel(par,numInLevel); i:=j+2; end; Result:=tmp; end;
function TCtrlTree.GetParent(inNumCode: String): TTreeNode; {功能:根据提供的全局编号找到对应的父节点 如果是第一层的节点,则父节点为nil 入口参数:inNumCode:String为全局编号 返回:全局编号对应的父节点 } var GoStep:integer; i:integer; j:integer; k:integer; SearChInNode:TTReeNode; ReturnNode:TTReeNode; begin //是第一层节点,返回nil; k:=GetTheLastPointPos(inNumCode); if k=0 then begin Result:=nil; Exit; end; //是第二层或第二层以上节点 i:=1; SearchInNode:=Items.GetFirstNode; while i < GetTheLastPointPos(inNumCode) do begin j:=GetPosAtBound(inNumCode,i); GoStep:=StrToInt(Copy(inNumCode,i,j-i+1)); if i=1 then //在第一层节点中搜索 begin ReturnNode:=SearchInNode; for k:=1 to GoStep-1 do ReturnNode:=ReturnNode.getNextSibling; end else //在第二层或第二层以上节点中搜索 begin GoStep:=StrToInt(Copy(inNumCode,i,j-i+1)); ReturnNode:=SearchInNode.Item[GoStep-1]; end; SearchInNode:=ReturnNode; i:=j+2 end; Result:=SearchInNode; end;
function TCtrlTree.LocateNodeInLevel(parNode: TTReeNode;LevelCode: integer): TTReeNode; {功能:根据父节点以及在兄弟节点中的编号找到对应的节点 如果要创建兄弟及自己,则新创建的节点的Text为Temp 入口参数:parNode: TTReeNode为父节点 LevelCode: integer为编号 返回:在parNode中编号为LevelCode的孩子节点 } var i:integer; j:integer; tmp:TTreeNode; tmps:TTreeNode; begin //父节点为空,是第一层节点 tmp:=nil; if parNode=nil then begin i:=1; tmps:=Items.GetFirstNode; while (tmps<>nil) and (i<=LevelCode) do begin tmp:=tmps; tmps:=tmps.getNextSibling; i:=i+1; end; i:=i-1; for j:=1 to LevelCode-i do tmp:=Items.AddChild(nil,''''Temp''''); Result:=tmp; end else //父节点不为空,正常处理 begin if parNode.Count<LevelCode then for i:= 1 to LevelCode-parNode.Count do Items.AddChild(parNode,''''Temp''''); Result:=parNode.Item[LevelCode-1]; end; end;
function TCtrlTree.GetPosAtBound(inString: String;inStart:Integer): Integer; {功能:根据起始位置找到下一个''''.''''的前一个位置 入口参数:inString: String节点编号 inStart: Integer当前处理层次的起始位置 返回:当前处理层次的结束位置 } var tmp:Char; pos:integer; begin pos:=inStart+1; while pos <= Integer(StrLen(PChar(inString))) do begin tmp:=inString[pos]; if tmp=''''.'' [1] [2] 下一页 [常用软件]TreeView 控件应用详解 [VB.NET程序]Henry手记-VB.NET中动态加载Treeview节点(二) [VB.NET程序]Henry手记-VB.NET中动态加载Treeview节点(一) [Delphi程序]Delphi中为TreeView添加单选和复选框 [Delphi程序]Object TreeView简要说明 [VB.NET程序]将listview中显示出来的记录拖到treeview中去 [VB.NET程序]vbscript版的TreeView,也就是树 [VB.NET程序]TreeView 控件树状控件的填充VB以及 VS.NET C#源代… [VB.NET程序]Treeview 控件的使用方法 [Web开发]在ASP.NET中使用Treeview控件和XML
|