zl程序教程

您现在的位置是:首页 >  后端

当前栏目

Delphi实现树型结构具体实例

实例 实现 结构 具体 Delphi 树型
2023-06-13 09:15:06 时间

复制代码代码如下:


unitUnit1;
interface
uses
 Windows,Messages,SysUtils,Variants,Classes,Graphics,Controls,Forms,
 Dialogs,StdCtrls,ComCtrls,DB,ADODB;
type
 PNodeInfoEx=^TNodeInfoEx;
 TNodeInfoEx=PackedRecord
     NodeID   :Integer;
     ParentID :Integer;
     NodeType :Integer;
     ChnNodeTitle:String;
     ImageIndex:SmallInt;
     SelectedIndex:SmallInt;
  end;
 TForm1=class(TForm)
   tv1:TTreeView;
   btn1:TButton;
   qry1:TADOQuery;
   procedurebtn1Click(Sender:TObject);
   procedureFormDestroy(Sender:TObject);
 private
   {Privatedeclarations}
   functionStaticBuildTree(TreeView:TTreeView):Boolean;
   functionAddTreeItem(TreeView:TTreeView;AddNodeInfo:PNodeInfoEx):TTreeNode;
   functionFindTreeItem(TreeView:TTreeView;CurNodeID:integer):TTreeNode;
 public
   {Publicdeclarations}
 end;
var
 Form1:TForm1;
implementation
{$R*.dfm}

functionTForm1.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
     ifqry1.RecordCount>0then
       begin
         qry1.First;
         whileNotqry1.Eofdo
         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
functionTForm1.AddTreeItem(TreeView:TTreeView;AddNodeInfo:PNodeInfoEx):TTreeNode;
var
   ParentNode:TTreeNode;
begin
   ParentNode:=FindTreeItem(Treeview,AddNodeInfo^.ParentID);
   IfParentNode<>nilthen
       Result:=Treeview.Items.AddChildObject(ParentNode,Trim(AddNodeInfo.ChnNodeTitle),Pointer(AddNodeInfo))
   else
       Result:=Treeview.Items.AddObject(ParentNode,Trim(AddNodeInfo.ChnNodeTitle),Pointer(AddNodeInfo));
   ifResult<>nilthen
   begin
       Result.ImageIndex   :=AddNodeInfo.ImageIndex;
       Result.SelectedIndex:=AddNodeInfo.SelectedIndex;
   end;
end;
//这里是判断是否存在其父结点
functionTForm1.FindTreeItem(TreeView:TTreeView;CurNodeID:integer):TTreeNode;
var
   i:Integer;
begin
 Result:=nil;
 fori:=0toTreeview.Items.Count-1do
 begin
     ifCurNodeID=PNodeInfoEx(Treeview.Items[i].Data)^.NodeIDthen
     begin
         Result:=Treeview.Items[i];
         Exit;
     end;
 end;
end;
//生成树结构
procedureTForm1.btn1Click(Sender:TObject);
begin
  StaticBuildTree(tv1)
end;
//在窗体释放时一定要把树结点中的结构体指针给释放掉,对于在Dispose时为什么要进行强制转型后释放,以前有专门的讲解,在此不在累述
procedureTForm1.FormDestroy(Sender:TObject);
var
   i:Integer;
begin
 fori:=0totv1.Items.Count-1do
 begin
      Dispose(PNodeInfoEx(tv1.Items[i].Data) )
 end;
end;
end.

复制代码代码如下:


//如何访问树结点?
procedureTForm1.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;