unit Treefunction;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls, Menus, ImgList, ExtCtrls, DB, DBTables, Grids, DBGrids; CONST SP1= '【'; SP2= '】'; C_DataBaseName='TreeDB';type TNodeData = Class public id:integer; node_name:string; node_no:string; parent_no:string; createdate:string; public constructor Create; destructor Destory; end;type TTreeManager = class private F_tree: TTreeView; procedure Set_tree(const Value: TTreeView); private procedure CreateTmpSet_ReadOnly( C_DataBaseName:string; var tmpSet: TQuery ) ; procedure CreateTmpSet(MyDBName:string; var tmpSet: TQuery);overload; procedure CreateTmpSet(MyDBName:string; var tmpSet: TQuery; var tmpSet1:TQuery);overload;
function getAllChildNode(aSelNode: TNodeData;var qryTree: TQuery): boolean; function getTreeNodeFromDB( qryTree:TQuery):TNodeData; function add_treeNode(aParentNo:TTreeNode;aNewNodeData:TNodeData): TTreeNode; function isHideNode(aNode: TTreeNode): Boolean; property _tree: TTreeView read F_tree write Set_tree; public function expand_treeNode( aSelNode:TTreeNode;beLoadAll:boolean = false ):boolean; procedure addHideNode(aParentNode: TTreeNode); constructor create( var aTree:TTreeView ); end;implementation
{ TTreeManager }procedure TTreeManager.CreateTmpSet(MyDBName: string; var tmpSet: TQuery); begin tmpSet := TQuery.Create(nil); //create Temp Query and connect to DataBase with tmpSet do begin DatabaseName := MyDBName; CachedUpdates := true; RequestLive := True; AutoCalcFields := true; AutoRefresh := true; end; end;function TTreeManager.add_treeNode(aParentNo: TTreeNode; aNewNodeData: TNodeData): TTreeNode; var aName:string; begin Assert( aNewNodeData <> nil ); aName:=aNewNodeData.node_no+sp1+aNewNodeData.node_name+sp2; try if aParentNo = Nil then//根节点 begin result := _tree.Items.AddObjectFirst( nil,aName, aNewNodeData); result.ImageIndex := 2; end else begin result :=_tree.Items.AddChildObject( aParentNo,aName, aNewNodeData ); result.ImageIndex := 2; end; except on E:exception do begin result := Nil; E.Create('添加节点出错!'+e.Message); end; end; end;procedure TTreeManager.CreateTmpSet(MyDBName: string; var tmpSet, tmpSet1: TQuery); begin CreateTmpSet( MyDBName, tmpSet ); CreateTmpSet( MyDBName, tmpSet1 ); end;procedure TTreeManager.CreateTmpSet_ReadOnly(C_DataBaseName: string; var tmpSet: TQuery); begin CreateTmpSet( C_DataBaseName, tmpSet ); tmpSet.RequestLive := False; end;function TTreeManager.expand_treeNode(aSelNode: TTreeNode; beLoadAll: boolean): boolean; var qryTemp,qryTree:TQuery; newNode :TNodeData; rvResult:TTreeNode; begin beLoadAll:=true; result := false; //判断树否为假借点,若是那麽删除所有节点 if isHideNode( aSelNode ) then aSelNode.DeleteChildren else exit;
newNode:=TNodeData.Create; try CreateTmpSet_ReadOnly( C_DataBaseName, qryTree ); CreateTmpSet_ReadOnly( C_DataBaseName, qryTemp ); Assert( aSelNode <> nil ); try if not getAllChildNode( TNodeData(aSelNode.Data),qryTree ) then exit; with qryTree do begin while not eof do begin newNode := getTreeNodeFromDB(qryTree); rvResult := add_treeNode( aSelNode,newNode ); addHideNode(rvResult); if ( rvResult <> nil ) then begin expand_treeNode( rvResult ,beLoadAll ); end; next; end;//while end;//with result := true; except on e:exception do e.Create('展开树节点异常'+e.Message ); end; finally qryTree.Free; qryTemp.Free; end; end;function TTreeManager.getAllChildNode(aSelNode: TNodeData; var qryTree: TQuery): boolean; begin begin Assert( aSelNode <> nil ); result := FALSE; try with qryTree do begin sql.Clear; sql.Add(FORMAT(' SELECT * FROM tree '+ ' WHERE '+ ' PARENT_NO = ''%S'' ', [ aSelNode.node_no ])); open; First; end; except on e: exception do e.Create('查找数据失败!'+e.Message); end; result := true; end; end;function TTreeManager.isHideNode(aNode: TTreeNode): Boolean; var child:TTreeNode; begin child:=aNode.getFirstChild; if child <> nil then begin if child.Text = 'hide' then result := true else result := false; end; end;procedure TTreeManager.Set_tree(const Value: TTreeView); begin F_tree := Value; end;constructor TTreeManager.create(var aTree: TTreeView); begin _tree:=aTree; end;function TTreeManager.getTreeNodeFromDB(qryTree: TQuery): TNodeData; begin result := TNodeData.Create; try with result,qryTree do begin id := FieldByName('ID').AsInteger; node_name := FieldByName('NODE_NAME').AsString; node_no := FieldByName('NODE_NO').AsString; parent_no := FieldByName('PARENT_NO').AsString; createdate:= FieldByName('CREATEDATE').AsString; end; except on E:exception do E.Create ('装载节点出错!'+e.Message); end; end;procedure TTreeManager.addHideNode(aParentNode: TTreeNode); begin _tree.Items.AddChildFirst( aParentNode,'hide' ); end;{ TNodeData }constructor TNodeData.Create; begin id :=0; node_name:=''; node_no:=''; parent_no:=''; createdate:=''; end;destructor TNodeData.Destory; begin end;end.
这里用数据库实现在一个TreeView的节点中保存除过Text的其他信息. 数据库的字段: TNodeData = Class public id:integer; node_name:string; node_no:string; parent_no:string; createdate:string; public constructor Create; destructor Destory; end; 与TNodeData 成员变量一致
放在 data 啊, 是個不錯的選擇
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, Menus, ImgList, ExtCtrls, DB, DBTables, Grids, DBGrids,
Treefunction;type
TForm1 = class(TForm)
imltree: TImageList;
ppmtree: TPopupMenu;
DataSource1: TDataSource;
Panel1: TPanel;
TreeView1: TTreeView;
Panel2: TPanel;
Splitter1: TSplitter;
Query1: TQuery;
N1: TMenuItem;
N2: TMenuItem;
N3: TMenuItem;
Database1: TDatabase;
qryTree: TQuery;
DBGrid1: TDBGrid;
procedure FormCreate(Sender: TObject);
procedure TreeView1Expanding(Sender: TObject; Node: TTreeNode;
var AllowExpansion: Boolean); private
F_treeManager: TTreeManager;
procedure Set_treeManager(const Value: TTreeManager);
private
{ Private declarations }
FaCrruNode: TNodeData;
procedure SetaCrruNode(const Value: TNodeData);
property aCrruNode:TNodeData read FaCrruNode write SetaCrruNode;
property _treeManager:TTreeManager read F_treeManager write Set_treeManager;
public
{ Public declarations } end;var
Form1: TForm1;
aparentnode:TTreenode;
implementation{$R *.dfm}{ TForm1 }procedure TForm1.SetaCrruNode(const Value: TNodeData);
begin
FaCrruNode := Value;
end;procedure TForm1.FormCreate(Sender: TObject);
var
aName:string;
begin
//初始化
aCrruNode := TNodeData.Create;
_treeManager:=TTreemanager.create(TreeView1);
// open query
Query1.Open; with qryTree do
begin
//Query Root
sql.Clear;
sql.Add(format(' select * from tree where PARENT_NO = ''%s'' ',['-1']));
try
open;
except
on e: exception do
e.Create('select Root Error!'+e.Message);
end;
//create nodedata
aCrruNode.id := FieldByName('ID').AsInteger;
aCrruNode.node_name := FieldByName('NODE_NAME').AsString;
aCrruNode.node_no := FieldByName('NODE_NO').AsString;
aCrruNode.parent_no := FieldByName('PARENT_NO').AsString;
aCrruNode.createdate:= FieldByName('CREATEDATE').AsString;
end; // with//add root
aName := aCrruNode.node_no+sp1+aCrruNode.node_name+sp2;
aparentnode := TreeView1.Items.AddChildObjectFirst(NIL,aName,aCrruNode);
aparentnode.ImageIndex:=1;
//加入一个假节点
TreeView1.Items.AddChildFirst(aparentnode,'hide');
end;
procedure TForm1.Set_treeManager(const Value: TTreeManager);
begin
F_treeManager := Value;
end;procedure TForm1.TreeView1Expanding(Sender: TObject; Node: TTreeNode;
var AllowExpansion: Boolean);
begin
_treeManager.expand_treeNode( Node );
AllowExpansion := true;
end;end.
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, Menus, ImgList, ExtCtrls, DB, DBTables, Grids, DBGrids;
CONST
SP1= '【';
SP2= '】';
C_DataBaseName='TreeDB';type
TNodeData = Class
public
id:integer;
node_name:string;
node_no:string;
parent_no:string;
createdate:string;
public
constructor Create;
destructor Destory;
end;type
TTreeManager = class
private
F_tree: TTreeView;
procedure Set_tree(const Value: TTreeView);
private
procedure CreateTmpSet_ReadOnly( C_DataBaseName:string; var tmpSet: TQuery ) ;
procedure CreateTmpSet(MyDBName:string; var tmpSet: TQuery);overload;
procedure CreateTmpSet(MyDBName:string; var tmpSet: TQuery; var tmpSet1:TQuery);overload;
function getAllChildNode(aSelNode: TNodeData;var qryTree: TQuery): boolean;
function getTreeNodeFromDB( qryTree:TQuery):TNodeData;
function add_treeNode(aParentNo:TTreeNode;aNewNodeData:TNodeData): TTreeNode;
function isHideNode(aNode: TTreeNode): Boolean;
property _tree: TTreeView read F_tree write Set_tree;
public
function expand_treeNode( aSelNode:TTreeNode;beLoadAll:boolean = false ):boolean;
procedure addHideNode(aParentNode: TTreeNode);
constructor create( var aTree:TTreeView ); end;implementation
{ TTreeManager }procedure TTreeManager.CreateTmpSet(MyDBName: string; var tmpSet: TQuery);
begin
tmpSet := TQuery.Create(nil); //create Temp Query and connect to DataBase
with tmpSet do
begin
DatabaseName := MyDBName;
CachedUpdates := true;
RequestLive := True;
AutoCalcFields := true;
AutoRefresh := true;
end;
end;function TTreeManager.add_treeNode(aParentNo: TTreeNode; aNewNodeData: TNodeData): TTreeNode;
var
aName:string;
begin
Assert( aNewNodeData <> nil );
aName:=aNewNodeData.node_no+sp1+aNewNodeData.node_name+sp2;
try
if aParentNo = Nil then//根节点
begin
result := _tree.Items.AddObjectFirst( nil,aName, aNewNodeData);
result.ImageIndex := 2;
end
else
begin
result :=_tree.Items.AddChildObject( aParentNo,aName, aNewNodeData );
result.ImageIndex := 2;
end;
except
on E:exception do
begin
result := Nil;
E.Create('添加节点出错!'+e.Message);
end;
end;
end;procedure TTreeManager.CreateTmpSet(MyDBName: string; var tmpSet, tmpSet1: TQuery);
begin
CreateTmpSet( MyDBName, tmpSet );
CreateTmpSet( MyDBName, tmpSet1 );
end;procedure TTreeManager.CreateTmpSet_ReadOnly(C_DataBaseName: string;
var tmpSet: TQuery);
begin
CreateTmpSet( C_DataBaseName, tmpSet );
tmpSet.RequestLive := False;
end;function TTreeManager.expand_treeNode(aSelNode: TTreeNode; beLoadAll: boolean): boolean;
var
qryTemp,qryTree:TQuery;
newNode :TNodeData;
rvResult:TTreeNode;
begin
beLoadAll:=true;
result := false;
//判断树否为假借点,若是那麽删除所有节点
if isHideNode( aSelNode ) then
aSelNode.DeleteChildren
else
exit;
newNode:=TNodeData.Create;
try
CreateTmpSet_ReadOnly( C_DataBaseName, qryTree );
CreateTmpSet_ReadOnly( C_DataBaseName, qryTemp );
Assert( aSelNode <> nil );
try
if not getAllChildNode( TNodeData(aSelNode.Data),qryTree ) then
exit; with qryTree do begin
while not eof do begin
newNode := getTreeNodeFromDB(qryTree);
rvResult := add_treeNode( aSelNode,newNode );
addHideNode(rvResult);
if ( rvResult <> nil ) then begin
expand_treeNode( rvResult ,beLoadAll );
end;
next;
end;//while
end;//with
result := true;
except
on e:exception do
e.Create('展开树节点异常'+e.Message );
end;
finally
qryTree.Free;
qryTemp.Free;
end;
end;function TTreeManager.getAllChildNode(aSelNode: TNodeData; var qryTree: TQuery): boolean;
begin
begin
Assert( aSelNode <> nil );
result := FALSE;
try
with qryTree do begin
sql.Clear;
sql.Add(FORMAT(' SELECT * FROM tree '+
' WHERE '+
' PARENT_NO = ''%S'' ',
[ aSelNode.node_no ]));
open;
First;
end;
except
on e: exception do
e.Create('查找数据失败!'+e.Message);
end;
result := true;
end;
end;function TTreeManager.isHideNode(aNode: TTreeNode): Boolean;
var
child:TTreeNode;
begin
child:=aNode.getFirstChild;
if child <> nil then begin
if child.Text = 'hide' then
result := true
else
result := false;
end;
end;procedure TTreeManager.Set_tree(const Value: TTreeView);
begin
F_tree := Value;
end;constructor TTreeManager.create(var aTree: TTreeView);
begin
_tree:=aTree;
end;function TTreeManager.getTreeNodeFromDB(qryTree: TQuery): TNodeData;
begin
result := TNodeData.Create;
try
with result,qryTree do begin
id := FieldByName('ID').AsInteger;
node_name := FieldByName('NODE_NAME').AsString;
node_no := FieldByName('NODE_NO').AsString;
parent_no := FieldByName('PARENT_NO').AsString;
createdate:= FieldByName('CREATEDATE').AsString;
end;
except
on E:exception do
E.Create ('装载节点出错!'+e.Message);
end;
end;procedure TTreeManager.addHideNode(aParentNode: TTreeNode);
begin
_tree.Items.AddChildFirst( aParentNode,'hide' );
end;{ TNodeData }constructor TNodeData.Create;
begin
id :=0;
node_name:='';
node_no:='';
parent_no:='';
createdate:='';
end;destructor TNodeData.Destory;
begin
end;end.
数据库的字段:
TNodeData = Class
public
id:integer;
node_name:string;
node_no:string;
parent_no:string;
createdate:string;
public
constructor Create;
destructor Destory;
end;
与TNodeData 成员变量一致