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

1.数据库结构与我的上一篇文章数据库->树型结构(TTreeView篇)完全相同

 

2.我的创建TVirtualStringTree树结构的单元文件代码

unit BuildVirtualTreeUnit;
 
interface
 
uses
  DB, ADODB, ComCtrls,Dialogs,VirtualTrees;
 
// 定义树结点对数据库表记录对应的结构体
type
  PNode = ^TNode;
  TNode = record
    FID:integer;    // 记录的ID号
    FCaption:string;
    FBM:TBookMark;  // 定位记录的指针(书签)
end;
 
function BuildTree(DataSet: TADODataSet; TV: TVirtualStringTree; SelfField,SelfName,ParentField:String):boolean;
 
implementation
 
function BuildTree(DataSet: TADODataSet; TV: TVirtualStringTree; 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: PVirtualNode):integer;
  var
    MyNode:PNode;
    Node:PVirtualNode;
  begin
    if FindKey(index,true) then
    begin
      Node:=TV.AddChild(ANode);
      MyNode := TV.GetNodeData(Node)  ;
      with DataSet do
      begin
        MyNode^.FID :=FieldValues[SelfField];
        MyNode^.FBM :=GetBookmark;
        MyNode^.FCaption := FieldValues[SelfName];
      end;

      Result:=1;
      while FindNext(index) do
      begin
       Node:=TV.AddChild(ANode);
        MyNode := TV.GetNodeData(Node);
        with DataSet do
        begin
          MyNode^.FID :=FieldValues[SelfField];
          MyNode^.FBM :=GetBookmark;
          MyNode^.FCaption := FieldValues[SelfName];
        end;

        Result:=Result+1;
      end;
    end
    else
      Result:=0;
  end;
  { 以下函数据以ANode 为结当,构造一棵属于自己的子树}
  procedure BuildMe(AIndex: integer; ANode: PVirtualNode);
  var
    NodeNum:integer;
    Node:PVirtualNode;
    i:integer;
  begin
    NodeNum:=GetChildNode(AIndex,ANode);
    //exit;
    if NodeNum>0 then
    begin
      if ANode=nil then Node:=TV.GetFirst
      else
        Node:=ANode.FirstChild;
      for i:=1 to NodeNum do
      begin
        BuildMe(PNode(TV.GetNodeData(Node))^.FID,Node);
        Node:=TV.GetNext(Node);
      end;
    end;
  end;
  // 组合部份
begin
  if (DataSet=nil) or (DataSet.Active =false) then
    Result:=false
  else if (TV=nil) then
    Result:=false
  else begin
    TV.Clear;
    BuildMe(0,nil);
    Result:=true;
  end;
end;
 
end.

 

 

3.要在TVirtualStringTree上显示文字,需要提供一个回调:

procedure TfrmMain.VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
  Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
var
  _pNode:PNode;
begin

  _pNode := Sender.GetNodeData(Node);
  if Assigned(_pNode) then
    CellText := _pNode.FCaption;

end;

 

5.当在TVirtualStringTree上点击时,可以获取当时项对应的数据库记录:

procedure TfrmMain.VSTClick(Sender: TObject);
var
  _pNode:PNode;
begin
  _pNode := VST.GetNodeData(VST.FocusedNode) ;
  //第一种方式
   ShowMessage(_pNode^.FCaption);

 //第二种方式
  DM.dsGroup_.GotoBookmark(_pNode.FBM);
  ShowMessage(DM.dsGroup_.FindField('group_name').AsString);
end;

 

 

4.调用

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

  

注:TVirtualStringTree的功能非常的强大,速度效率绝非TTreeView能比的。自然使用起来就复杂,但是只要掌握了它的原理,就很好理解了.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值