数据库->树型结构(TTreeView篇)

1.首先看一下我的数据库结构:

  id                      :    int

  group_name     :    int

  parent_id          :    int

  不用解释,相信大家一看就明白。

 

2.delphi中新建一个datemodel,命名为dm,和一个窗体frmMain

   在dm中放入tadoconnection,和一个tadodataset,并连接上数据库。

   在frmMain上放入一个TTreeView.

 

3.我的创建树结构的单元文件代码:

 

unit BuildTreeUnit;
 
interface
 
uses
  DB, ADODB, ComCtrls,Dialogs;
 
// 定义树结点对数据库表记录对应的结构体
type
  PNode = ^TNode;
  TNode = record
    FID:integer;    // 记录的ID号
    FBM:TBookMark;  // 定位记录的指针(书签)
end;
 
function BuildTree(DataSet: TADODataSet; TV: TTreeView; SelfField,SelfName,ParentField:String):boolean;
 
implementation
 
function BuildTree(DataSet: TADODataSet; TV: TTreeView; SelfField,SelfName,ParentField:String):boolean;
  { 以下子函数为在表中查找第一个PNode=AIndex的记录}
  function FindKey(AIndex: integer; FFirst:boolean): boolean;
  begin
    Result:=DataSet.Locate(ParentField,AIndex,[loCaseInsensitive]);
  end;
  { 以下函数在FindKey的基础上找出下一个符合的记录}
  function FindNext(AIndex: integer): boolean;
  begin
    DataSet.Next;
    if DataSet.Eof then
      Result:=false
    else
      Result:=DataSet.FieldValues[ParentField]=AIndex;
    if not Result then DataSet.Prior;
  end;
  { 以下函数据构造当前结点的一级子树 }
  function GetChildNode(index: integer; ANode: TTreeNode):integer;
  var
    MyNode:PNode;
    Node:TTreeNode;
  begin
    if FindKey(index,true) then
    begin
      new(MyNode);
      with DataSet do
      begin
        MyNode^.FID :=FieldValues[SelfField];
        MyNode^.FBM :=GetBookmark;
      end;
      Node:=TV.Items.AddChild(ANode,DataSet.FieldValues[SelfName]);
      Node.Data:=MyNode;
      Result:=1;
      while FindNext(index) do
      begin
        new(MyNode);
        with DataSet do
        begin
          MyNode^.FID :=FieldValues[SelfField];
          MyNode^.FBM :=GetBookmark;
        end;
        Node:=TV.Items.AddChild(ANode,DataSet.FieldValues[SelfName]);
        Node.Data:=MyNode;
        Result:=Result+1;
      end;
    end
    else
      Result:=0;
  end;
  { 以下函数据以ANode 为结当,构造一棵属于自己的子树}
  procedure BuildMe(AIndex: integer; ANode: TTreeNode);
  var
    NodeNum:integer;
    Node:TTreeNode;
    i:integer;
  begin
    NodeNum:=GetChildNode(AIndex,ANode);
    if NodeNum>0 then
    begin
      if ANode=nil then Node:=TV.Items.GetFirstNode
      else
        Node:=ANode.getFirstChild;
      for i:=1 to NodeNum do
      begin
        BuildMe(PNode(Node.Data)^.FID,Node);
        Node:=ANode.GetNextChild(Node);
      end;
    end;
  end;
  // 组合部份
begin
  showmessage('here');
  if (DataSet=nil) or (DataSet.Active =false) then
    Result:=false
  else if (TV=nil) then
    Result:=false
  else begin
    TV.Items.Clear;
    BuildMe(0,nil);
    Result:=true;
  end;
end;
 
end.

 

4.调用: 

 
BuildTree(DM.dsGroup_,TV,'id','group_name','parent_id');

 

 

  • 0
    点赞
  • 0
    收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值