zoukankan      html  css  js  c++  java
  • Delphi实现树型结构

    unit Unit1;
    interface
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, ComCtrls, DB, ADODB;
    type
      PNodeInfoEx = ^TNodeInfoEx;
      TNodeInfoEx = Packed Record
          NodeID    : Integer;
          ParentID  : Integer;
          NodeType  : Integer;
          ChnNodeTitle : String;
          ImageIndex: SmallInt;
          SelectedIndex: SmallInt;
       end;
      TForm1 = class(TForm)
        tv1: TTreeView;
        btn1: TButton;
        qry1: TADOQuery;
        procedure btn1Click(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
      private
        { Private declarations }
        function StaticBuildTree(TreeView:TTreeView ):Boolean;
        function AddTreeItem(TreeView:TTreeView; AddNodeInfo:PNodeInfoEx):TTreeNode;
        function FindTreeItem(TreeView:TTreeView; CurNodeID:integer): TTreeNode;
      public
        { Public declarations }
      end;
    var
      Form1: TForm1;
    implementation
    {$R *.dfm}
     
    function TForm1.StaticBuildTree(TreeView:TTreeView ):Boolean;
    var
      AddNodeInfo : PNodeInfoEx;
    begin
      Result := False;
      qry1.LoadFromFile('c:/AdminixTree.xml');//这里以XML文件做为数据源
      Treeview.Items.BeginUpdate;//记住:在进行批量添加数据时要使用BeginUpdate,来暂时关闭由于添加数据而触发的某些事件(如OnChange事件等)
      Treeview.Items.Clear;//清空Treeview
      try
        try
          if qry1.RecordCount >0 then
            begin
              qry1.First;
              while Not qry1.Eof do
              begin
                New(AddNodeInfo) ;//生成结构体
                AddNodeInfo^.NodeID := qry1.FieldByName('NODE_ID').AsInteger;
                AddNodeInfo^.ParentID := qry1.FieldByName('PARENT_ID').AsInteger;
                AddNodeInfo^.NodeType := qry1.FieldByName('NodeType').AsInteger;
                AddNodeInfo^.ChnNodeTitle := qry1.FieldByName('ChnNodeTitle').AsString;
                AddNodeInfo^.ImageIndex := qry1.FieldByName('ImageIndex').AsInteger;
                AddNodeInfo^.SelectedIndex := qry1.FieldByName('SelectedIndex').AsInteger;
                AddTreeItem(Treeview,AddNodeInfo);//把结构体的指针存到Treeview中
                qry1.Next;
              end;
            end;
        except
          Application.MessageBox('生成树结点失败',MB_ICONSTOP+MB_OK);
          raise;//向上级抛异常
        end;
        qry1.Close;
        Result := True;
      finally
        Treeview.Items.EndUpdate;
      end;
    end;
    //在加入结点时,应先判断加入的是父结点还是子结点,判断的依据是在已存在的树结点中是否存在该结点的ParentID
    function TForm1.AddTreeItem(TreeView:TTreeView; AddNodeInfo:PNodeInfoEx):TTreeNode;
    var
        ParentNode: TTreeNode;
    begin
        ParentNode := FindTreeItem(Treeview,AddNodeInfo^.ParentID);
        If ParentNode <> nil then
            Result := Treeview.Items.AddChildObject(ParentNode, Trim(AddNodeInfo.ChnNodeTitle), Pointer(AddNodeInfo))
        else
            Result := Treeview.Items.AddObject(ParentNode, Trim(AddNodeInfo.ChnNodeTitle), Pointer(AddNodeInfo));
        if Result<>nil then
        begin
            Result.ImageIndex    := AddNodeInfo.ImageIndex;
            Result.SelectedIndex := AddNodeInfo.SelectedIndex;
        end;
    end;
    //这里是判断是否存在其父结点
    function TForm1.FindTreeItem(TreeView:TTreeView; CurNodeID:integer): TTreeNode;
    var
        i : Integer;
    begin
      Result := nil;
      for i := 0 to Treeview.Items.Count-1 do
      begin
          if CurNodeID=PNodeInfoEx(Treeview.Items[i].Data)^.NodeID then
          begin
              Result := Treeview.Items[i];
              Exit;
          end;
      end;
    end;
    //生成树结构
    procedure TForm1.btn1Click(Sender: TObject);
    begin
       StaticBuildTree (tv1)
    end;
    //在窗体释放时一定要把树结点中的结构体指针给释放掉,对于在Dispose时为什么要进行强制转型后释放,以前有专门的讲解,在此不在累述
    procedure TForm1.FormDestroy(Sender: TObject);
    var
        i : Integer;
    begin
      for i := 0 to tv1.Items.Count-1 do
      begin
           Dispose( PNodeInfoEx(tv1.Items[i].Data)  )
      end;
    end;
    end.
    View Code
    //如何访问树结点?
    procedure TForm1.tv1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    var
      pNode:TTreeNode;
    begin
      pNode:=tv1.GetNodeAt(x,y);
      if (pNode<>nil) and  (Button=mbleft) then
       ShowMessage(PNodeInfoEx(pNode.Data)^.ChnNodeTitle);
    end;
    View Code
  • 相关阅读:
    redis搭建集群并用TreeSoft管理
    使用windows任务计划程序自动清除C盘缓存文件
    深入理解JavaScript事件循环机制
    redux源码解读(二)
    redux源码解读(一)
    create-react-app源码解读之为什么不搞个山寨版的create-react-app呢?
    深入理解CSS系列(二):为什么height:100%不生效?
    深入理解CSS系列(一):理解CSS的盒子模型
    搭建一个交互式的前端构建环境.md
    实习这件小事(一位大四狗的前端实习经历)
  • 原文地址:https://www.cnblogs.com/china1/p/3377681.html
Copyright © 2011-2022 走看看