诚心请教这个单元在树中起到什么作用呢?

DFans 2009-03-11 11:38:50
加精
{================ Free TIBXTreeView component for IBX =======================
Igor Ilyinsky, 2001, www.sinn.ru/~mapnn (mapnn@sinn.ru)
==============================================================================
}
unit IBXtrees;

interface

uses ComCtrls, DB, Classes, SysUtils, IBDatabase, IBSQL;

type

PItemRec = ^ItemRec;
ItemRec = record
Id : integer;
Parent: integer;
CCount: integer;
end;

TIBXTreeView=class(TTreeView)
private
IBConnection : TIBDatabase;
IBTransaction : TIBTransaction;
IBTableName : String;
IBSQL : TIBSQL;
procedure BuildNode(Node:TTreeNode);
protected
procedure Delete(Node: TTreeNode); override;
function CanExpand(Node: TTreeNode): Boolean; override;
// Rebuild children for ParentNode
procedure RebuildNode(ParentNode: TTreeNode; Node_Id: integer); virtual;
public
procedure BuildTree(RootName: String);
procedure ClearTree;
//
constructor Create(AOwner:TComponent); override;
destructor Destroy; override;
//
procedure InsertNode(Parent_Id: integer; Name: String);
//
procedure MoveNode(Node_Id, NewParent_Id: integer);
//
procedure RenameNode(Node:TTreeNode; Name: String);
//
procedure DeleteNode(Node:TTreeNode);
//
function GetId(Node: TTreeNode) : Integer;
//
function GetNode(Id: Integer) : TTreeNode;
published
property Database : TIBDatabase read IBConnection write IBConnection;
property Transaction : TIBTransaction read IBTransaction write IBTransaction;
property TableName : string read IBTableName write IBTableName;
end;

procedure Register;

implementation

function TIBXTreeView.GetId(Node: TTreeNode) : Integer;
var R: PItemRec;
begin
R:=PItemRec(Node.Data);
Result := R^.ID;
end;

function TIBXTreeView.GetNode(Id: Integer) : TTreeNode;
var R: PItemRec;
i: integer;
begin
Result:=nil;
i:=0;
While i < Items.Count do begin
R:=PItemRec(Items[i].Data);
if R^.ID = Id then begin
Result := Items[i];
break;
end;
inc(i);
end;
end;

constructor TIBXTreeView.Create(AOwner:TComponent);
begin
inherited Create(AOwner);
IBSQL:=TIBSQL.Create(Self);
end;

procedure TIBXTreeView.Delete(Node: TTreeNode);
begin
inherited Delete(Node);
if Assigned(Node) then
if Assigned(Node.Data) then Dispose(PItemRec(Node.Data));
end;

function TIBXTreeView.CanExpand(Node: TTreeNode): Boolean;
begin
Result:=inherited CanExpand(Node);
if Assigned(Node.Data) then
Items.BeginUpdate;
BuildNode(Node);
Items.EndUpdate;
end;

destructor TIBXTreeView.Destroy;
begin
IBSQL.Free;
inherited;
end;

procedure TIBXTreeView.BuildNode(Node:TTreeNode);
var NewNode: TTreeNode;
R: PItemRec;
begin
if not IBTransaction.inTransaction then IBTransaction.StartTransaction;
IBSQL.Close;
IBSQL.Sql.Text:='select * from '+IBTableName+' where PARENT=:Parent ';
R:=Node.Data;
IBSQL.ParamByName('Parent').asInteger:=R^.Id;
Node.DeleteChildren;
IBSQL.ExecQuery;
while not IBSQL.EOF do
begin
New(R);
R^.Id:=IBSQL.FieldByName('ID').asInteger;
R^.Parent:=IBSQL.FieldByName('PARENT').asInteger;
R^.CCount:=IBSQL.FieldByName('CCOUNT').asInteger;
NewNode:=Items.AddChild(Node,Trim(IBSQL.FieldByName('NAME').asString));
NewNode.Data:=PItemRec(R);
NewNode.HasChildren:=R^.CCount > 0;
if assigned(Images) then begin
NewNode.ImageIndex:=2;
NewNode.SelectedIndex:=3;
end;
IBSQL.Next;
end;
IBSQL.Close;
end;

procedure TIBXTreeView.InsertNode(Parent_Id: integer; Name: String);
var ParentNode: TTreeNode;
begin
if not IBTransaction.inTransaction then IBTransaction.StartTransaction;
IBSQL.Close;
IBSQL.Sql.Text:='insert into '+IBTableName+' (PARENT,NAME) values(:Parent,:Name)';
IBSQL.ParamByName('Parent').asInteger:=Parent_Id;
IBSQL.ParamByName('Name').asString:=Name;
IBSQL.ExecQuery;
IBTransaction.Commit;
ParentNode:=GetNode(Parent_id);
if ParentNode <> nil then RebuildNode(ParentNode, -1); // if parent visible
end;

procedure TIBXTreeView.MoveNode(Node_Id, NewParent_Id: integer);
var Node,NodeParent: TTreeNode;
begin
if Node_Id = NewParent_Id then raise exception.create('Parent Node can not be equal Selected Node!');
if Node_Id = 0 then raise exception.create('Root Node can not be moved!');
if not IBTransaction.inTransaction then IBTransaction.StartTransaction;
IBSQL.Close;
// TEST CICLE NODE
IBSQL.Sql.Text:='select * from GETPARENTS(:Id)';
IBSQL.ParamByName('Id').asInteger:=NewParent_Id;
IBSQL.ExecQuery;
while not IBSQL.EOF do begin
if IBSQL.FieldByName('DID').asInteger = Node_Id then
raise exception.create('Cicle Node!');
IBSQL.Next;
end;
IBSQL.Close;
// UPDATE
IBSQL.Sql.Text:='update '+IBTableName+' set PARENT=:Parent where ID=:ID';
IBSQL.ParamByName('Parent').asInteger:=NewParent_Id;
IBSQL.ParamByName('ID').asInteger:=Node_Id;
IBSQL.ExecQuery;
IBTransaction.Commit;
Node:=GetNode(Node_Id);
if (Node <> nil) and Node.Parent.Expanded then items.delete(Node);
NodeParent:=GetNode(NewParent_Id);
if (NodeParent <> nil) then RebuildNode(NodeParent,Node_Id); // if newparent visible
end;

procedure TIBXTreeView.RenameNode(Node:TTreeNode; Name: String);
var R: PItemRec;
begin
if Node.Parent = nil then raise exception.create('Root Node can not be renamed!');
if not IBTransaction.inTransaction then IBTransaction.StartTransaction;
IBSQL.Close;
IBSQL.Sql.Text:='update '+IBTableName+' set NAME=:Name where ID=:ID';
R:=Node.Data;
IBSQL.ParamByName('ID').asInteger:=R^.ID;
IBSQL.ParamByName('Name').asString:=Name;
IBSQL.ExecQuery;
IBTransaction.Commit;
RebuildNode(Node.Parent,R^.ID);
end;

procedure TIBXTreeView.DeleteNode(Node:TTreeNode);
var R: PItemRec;
begin
if Node.Parent = nil then raise exception.create('Root Node can not be deleted!');
if Node.HasChildren then raise exception.Create('This Node has Children!');
if not IBTransaction.inTransaction then IBTransaction.StartTransaction;
IBSQL.Close;
IBSQL.Sql.Text:='delete from '+IBTableName+' where ID=:ID';
R:=PItemRec(Node.Data);
IBSQL.ParamByName('ID').asInteger:=R^.ID;
IBSQL.ExecQuery;
IBTransaction.Commit;
RebuildNode(Node.Parent,-1);
end;

procedure TIBXTreeView.BuildTree(RootName: String);
var RootNode: TTreeNode;
R: PItemRec;
begin
IBSQL.Database:=IBConnection;
IBSQL.Transaction:=IBTransaction;
if (not assigned(IBConnection)) or (not assigned(IBTransaction)) or (IBTableName = '') then
raise exception.create('IBConnection,IBTransaction or IBTableName is not defined!');
items.BeginUpdate;
ClearTree;
RootNode:=items.Add(nil, RootName); { Add a root node }
if assigned(Images) then begin
RootNode.ImageIndex:=0;
RootNode.SelectedIndex:=1;
end;
new(r);
r^.id:=0; // id root = 0 !!!
RootNode.Data:=r;
BuildNode(RootNode);
RootNode.Expand(False);
Items.EndUpdate;
end;

{Rebuild children for ParentNode}
procedure TIBXTreeView.RebuildNode(ParentNode: TTreeNode; Node_Id: integer);
var Node: TTreeNode;
begin
if ParentNode <> nil then begin
items.BeginUpdate;
BuildNode(ParentNode);
ParentNode.Expand(False);
if Node_Id >= 0 then begin
Node:=GetNode(Node_Id);
if Node <> nil then Node.Selected:=True;
end;
items.EndUpdate;
end;
end;

procedure TIBXTreeView.ClearTree;
begin
While Items.Count>0 do Items.Delete(Items[0]);
end;

procedure Register;
begin
RegisterComponents('InterBase', [TIBXTreeView]);
end;

end.
...全文
758 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
书生行走 2011-12-04
  • 打赏
  • 举报
回复
它在整个数据库设计中如何实现,作用就是读取数据吗,真的不懂,请指教
yct0605 2009-03-18
  • 打赏
  • 举报
回复
应该是从数据库中动态读取数据,然后用树状控件显示出来树结构。
kevin 2009-03-14
  • 打赏
  • 举报
回复

代码写的相当好.

作者是继承TTreeview编写树型控件,
并在它的基础上增加了三个属性: 数据库,事务还有 表名。

1、procedure TIBXTreeView.BuildTree(RootName: String);
传入树的根节点,并将给Record结构的ID赋初始值,然后调用BuildNode(Node)来遍历tablename的行,将其存入到Record结构,并填充BuildNode(Node)里
node的子节点。这里没有递归,似乎存在一点问题,无法再提取出Node的下个中间层的子节点。

2、其他的我和三楼相同。


boss1215 2009-03-12
  • 打赏
  • 举报
回复
努力學習中~謝謝分享^^
youyouzui 2009-03-12
  • 打赏
  • 举报
回复
似乎是呢 。。。好像对啊 。。。。。
youyouzui 2009-03-12
  • 打赏
  • 举报
回复
这个有点看不懂呢
nbman2013 2009-03-12
  • 打赏
  • 举报
回复
对树的操作,很全,很经典的代码
xjlnjut730 2009-03-11
  • 打赏
  • 举报
回复
不太清楚,有空再研究研究。
cht_1988 2009-03-11
  • 打赏
  • 举报
回复
学习了谢谢分享
bdmh 2009-03-11
  • 打赏
  • 举报
回复
这个类应该把字段'PARENT'放开,作为一个属性,否则他人使用时,只能用'PARENT'作为字段名,应该想dxtreelist那样,设置keyid和parentid
不得闲 2009-03-11
  • 打赏
  • 举报
回复
如楼上所说
bdmh 2009-03-11
  • 打赏
  • 举报
回复
TIBXTreeView.BuildNode(Node:TTreeNode);
根据Node.Data中存储的id值,从数据库中取得该id记录的所属下级记录,这也是形成树形结构的核心
de410 2009-03-11
  • 打赏
  • 举报
回复
关于树操作的单元,树的生成,节点的添加、删除、移动、修改、刷新等功能
lgx0914 2009-03-11
  • 打赏
  • 举报
回复
procedure BuildTree(RootName: String);//创建树
procedure ClearTree;//清空树
procedure InsertNode(Parent_Id: integer; Name: String);//插入节点
procedure MoveNode(Node_Id, NewParent_Id: integer);//移动节点
procedure RenameNode(Node:TTreeNode; Name: String);//重命名节点
procedure DeleteNode(Node:TTreeNode);//删除节点
function GetId(Node: TTreeNode) : Integer;//获得节点ID
function GetNode(Id: Integer) : TTreeNode;//通过ID获得节点信息
bdmh 2009-03-11
  • 打赏
  • 举报
回复
这个好像可以从数据库读取数据然后生成树形结构
lclichao2006 2009-03-11
  • 打赏
  • 举报
回复
学习了谢谢分享
cnlong 2009-03-11
  • 打赏
  • 举报
回复
good
chenzhaochun 2009-03-11
  • 打赏
  • 举报
回复
哇~好多的代码~了解了解~

2,497

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 数据库相关
社区管理员
  • 数据库相关社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧