`
ivfh
  • 浏览: 59941 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
最近访客 更多访客>>
社区版块
存档分类
最新评论

Delphi下Treeview控件基于节点编号的访问

阅读更多

有时我们需要保存和重建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='.' then
             Break
         else
             pos:=pos+1;
     end;
     Result:=pos-1;
end;

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

function TCtrlTree.InsertAsFinalChild(inString: String; inNode: TTreeNode):TTReeNode;
{功能:为当前节点插入一个孩子节点,位置为最后
 入口参数:inString: String为节点编号为待插入节点的字符串
           inNode: TTreeNode,当前节点
}
begin
    Result:=Items.AddChild(inNode,inString);
end;

function TCtrlTree.InsertAsPreviousSibling(inString: String;
  inNode: TTreeNode):TTReeNode;
{功能:为当前节点插入一个前导的兄弟节点
 入口参数:inString: String为节点编号为待插入节点的字符串
           inNode: TTreeNode,当前节点
}
begin
    Result:=Items.AddChildFirst(inNode,inString);
end;

end.

分享到:
评论

相关推荐

    delphi自定义控件_treeview控件加强

    本主题将深入探讨如何对Delphi的内置TreeView控件进行增强,以实现更丰富的功能,例如增删改及拖拽操作。我们将以一个名为`TmyTreeView`的自定义控件为例进行讲解。 首先,`TmyTreeView`是对原生`TTreeView`控件的...

    一个Delphi TreeView节点添加、删除操作实例.rar

    一个Delphi TreeView节点添加、删除操作实例,删除节点时请确认主节点内没有子节点,请删除全部子节点后再删除,相关代码:  addtxt:=trim(e1.text); //删除空格后得到添加节点的文本  addtxtlength:=length(add...

    TreeView控件节点添加练习程序Delphi版..rar

    这个“TreeView控件节点添加练习程序”是专为Delphi开发者设计的一个实践项目,旨在帮助他们熟悉如何在TreeView中动态添加、删除和管理节点。 在Delphi中,TreeView控件的基础类是TTreeView,它继承自TControl。...

    Q693643.rar delphi Treeview的节点移动和保存节点位置

    在Delphi编程中,TreeView控件是常用的图形用户界面组件,用于展示层次化的数据结构。本文将深入探讨如何实现Treeview节点的移动以及保存和恢复节点的位置。 首先,我们需要了解Delphi中的TreeView组件。它基于VCL...

    TreeView之间的节点拖动Delphi源码

    在Delphi编程环境中,开发人员经常使用TreeView控件来展示层次化的数据结构,因为它直观且易于操作。"TreeView之间的节点拖动"是一个重要的功能,它允许用户通过鼠标拖放操作来重新排列节点,从而实现数据的动态修改...

    删除TreeView节点以及其子节点

    1. **TreeView控件**:TreeView是Windows应用程序中常用的控件,用于展示层次结构的数据,比如文件系统、组织结构等。它包含一系列的节点,每个节点可以有子节点。 2. **删除节点**:在Delphi中,可以使用`TreeView...

    delphi treeview 加载时 改变字体颜色

    通过上述分析,我们可以看到,在Delphi中利用TreeView控件结合数据库查询和事件处理,可以实现在加载时动态改变节点字体颜色的功能。这不仅增强了应用程序的视觉效果,也提高了数据展示的灵活性和准确性。对于需要...

    Q693527.rar delphi treeview的子节点图标

    在Delphi编程中,TreeView控件是一个非常常用且功能强大的组件,它用于显示层次结构的数据。这个控件允许用户以树形结构查看信息,每个节点可以代表一个对象或数据项,而子节点则表示该对象的子部分或者相关联的信息...

    [Delphi]TreeView使用笔记

    Delphi 的 TreeView 控件是树形结构的视图控件,用于展示层次结构的数据。TreeView 由节点构成,通过对 TreeView.items 属性进行操作。Items 是一个 TTreeNodes 对象,这是一个 TTreeNode 集合。 一、TTreeNodes ...

    delphi treeview的使用

    在这个主题中,我们将深入探讨如何使用Delphi的TreeView控件进行动态创建、删除和修改节点,以及如何利用它来展示目录结构。 1. **动态创建节点** 在Delphi中,你可以通过TTreeNode对象来创建新的节点。首先,你...

    Delphi7实现TreeView之间节点拖动

    在Delphi7中,TreeView控件是用于展示层次结构数据的一种常见组件,它通常用于文件系统、数据库结构或任何有层级关系的数据展示。本话题主要关注如何实现TreeView之间的节点拖动功能,这是一个增强用户交互性和操作...

    delphi源码检测TreeView的各个节点的重复情况

    在Delphi编程中,TreeView控件是常用的图形用户界面组件,用于展示层次化的数据结构。在某些场景下,我们可能需要确保每个节点都是唯一的,没有重复。本篇将详细讲解如何检测并处理TreeView中的重复节点,以及两种...

    TreeView增加子节点父节点例子.rar

    1. **TreeView控件**:在Delphi中,TTreeView是VCL库中的一个控件,它基于Windows API的TVirtualTree控件,用于显示具有层级关系的数据。每个节点可以有子节点,并且可以通过图标和文本来表示。 2. **动态添加节点*...

    Delphi检测TreeView树的重复子节点..rar

    在Delphi编程中,TreeView控件是常用的图形用户界面组件,用于展示层次化的数据结构。在实际应用中,我们可能需要确保每个子节点都是唯一的,避免出现重复的节点。本教程将深入探讨如何在Delphi中检测并处理TreeView...

    Delphi 树的遍历

    在 Delphi 中,我们可以使用 TTreeView 控件来呈现树结构,并通过 TTreeNode 类型来表示每个节点。TTreeView 控件提供了多种遍历方法,如 EnumChildren、EnumChildNodes 等,但为了实现题目中的需求,递归算法是最...

    将数据库数据添加到TreeView控件中(DeLphi)..rar

    在DeLphi编程环境中,将数据库数据添加到TreeView控件是一项常见的任务,它允许用户以树形结构查看和操作数据库中的信息。以下是一份详细的知识点解析,介绍如何实现这一功能: 1. **TreeView控件**:TreeView是...

    TreeView只展开一个节点

    在默认情况下,`TreeView`控件允许用户自由地展开多个节点,以便查看不同级别的信息。然而,有时候我们可能需要限制用户只能看到一个节点的展开状态,以实现特定的界面交互效果或简化用户操作。这就涉及到如何实现...

    DelphiXE 10.3 TreeView添加复选框 源码.zip

    1. **TreeView组件**:首先,我们要了解 Delphi 的 TTreeView 控件,它是 VCL(Visual Component Library)库中的一个标准组件,用于显示层次结构数据。在界面上,它通常以树状结构展示数据,每个节点可以有子节点。...

    Delphi结合数据库生成Treeview树控菜单视图类.rar

    Delphi树形菜单类以及例子,结合数据库生成Treeview树控菜单视图,你可了解下如何按照节点在数据库中的编号查找节点、如何查找节点在数据库中的数据、填充节点等。这个类通过数据库中的数据自动添加到Treeview控件中...

    delphi树控件带数据存取Tmytreeview自定义控件

    "Tmytreeview"是一个针对标准Delphi TreeView控件进行增强的自定义控件,它扩展了标准组件的功能,以支持更丰富的交互和数据管理操作。 首先,让我们详细了解"Tmytreeview"的特性: 1. **增删改功能**:...

Global site tag (gtag.js) - Google Analytics