记得给分记得给分哦记得给分哦记得给分哦记得给分哦!!!
unit tree;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, StdCtrls, Menus, DB, DBTables, ImgList;
type
TForm1 = class(TForm)
TestTree: TTreeView;
MemoTree: TMemo;
PopupNode: TPopupMenu;
N1: TMenuItem;
N2: TMenuItem;
TestTable: TTable;
Button1: TButton;
ImageList1: TImageList;
procedure FormActivate(Sender: TObject);
procedure TestTreeChange(Sender: TObject; Node: TTreeNode);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure N1Click(Sender: TObject);
procedure N2Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure TestTreeEdited(Sender: TObject; Node: TTreeNode;
var S: String);
procedure TestTreeCustomDrawItem(Sender: TCustomTreeView;
Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
private
{ Private declarations }
procedure AddTreeChild(sItem: string;FatherNode: TTreeNode);
procedure DeleteNode(CurrentNode: TTreeNode);
public
{ Public declarations }
end;
type
Node = record
sItem: string;
end;
pNode = ^Node;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormActivate(Sender: TObject);
var
tNode: TTreeNode;
i,nChildNum: Integer;
sChildItem: string;
pItem: PNode;
begin
try
TestTree.Items.Clear; //清空树型列表
TestTable.Active := true; //打开表
TestTable.FindKey(['ITEM']); //定位记录到根节点
tNode := TestTree.Items.Add(nil,TestTable.FieldByName('Name').AsString); //添加根节点
New(pItem); //保存根节点在树中的标识
pItem.sItem := 'ITEM';
tNode.Data := PItem;
//用递归添加所有子节点
nChildNum := TestTable.FieldByName('ChildNum').AsInteger; //获得子节点数目
for i := 1 to nChildNum do //添加子节点
begin
sChildItem := 'ITEM_' + IntToStr(i);
AddTreeChild(sChildItem,tNode);
end;
except
Application.MessageBox('数据库出错!','错误');
end
end;
//功能:递归函数,用来添加节点
//参数:sItem 节点在树中的标识
// FatherNode 节点的父节点
procedure TForm1.AddTreeChild(sItem: string;FatherNode: TTreeNode);
var
tNode: TTreeNode;
i,nChildNum: Integer;
sChildItem: string;
pItem: pNode;
begin
try
TestTable.FindKey([sItem]); //定位到该节点的记录
tNode := TestTree.Items.AddChild(FatherNode,TestTable.FieldByName('Name').AsString); //添加该节点
New(pItem); //保存该节点在树中的标识
pItem.sItem := sItem;
tNode.Data := pItem;
nChildNum := TestTable.FieldByName('ChildNum').AsInteger; //添加该节点的所有子节点
for i := 1 to nChildNum do
begin
sChildItem := sItem + '_' + IntToStr(i);
AddTreeChild(sChildItem,tNode); //递归调用
end;
except
Application.MessageBox('数据库出错!','错误');
end;
end;
//当选中一个节点时,显示节点的内容
procedure TForm1.TestTreeChange(Sender: TObject; Node: TTreeNode);
begin
TestTable.FindKey( [ pNode(Node.Data).sItem ] );
MemoTree.Text := TestTable.FieldByName('Text').AsString;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var
i: Integer;
begin
for i := 1 to TestTree.Items.Count do //释放NEW的空间
Dispose(TestTree.Items[i-1].Data);
if TestTable.Active then //关闭表
TestTable.Close;
end;
//右键选择添加时,为当前节点添加一个子节点
procedure TForm1.N1Click(Sender: TObject);
var
tChildNode: TTreeNode;
sChildItem: string;
pItem: pNode;
begin
tChildNode := TestTree.Items.AddChild(TestTree.Selected,'NEW'); //添加子节点
sChildItem := pNode(TestTree.Selected.Data).sItem; //保存子节点在树中的标识
sChildItem := sChildItem + '_' + IntToStr(TestTree.Selected.Count);
New(pItem);
pItem.sItem := sChildItem;
tChildNode.Data := pItem;
try
//定位到当前节点的记录,将其子节点数加一
TestTable.FindKey( [ pNode(TestTree.Selected.Data).sItem ] );
TestTable.Edit;
TestTable.FieldByName('ChildNum').AsInteger := TestTable.FieldByName('ChildNum').AsInteger+1;
TestTable.Post;
//添加子节点记录
TestTable.Insert;
TestTable.FieldByName('Node').AsString := sChildItem;
TestTable.FieldByName('ChildNum').AsInteger := 0;
TestTable.FieldByName('Name').AsString := 'NEW';
TestTable.Post;
except
Application.MessageBox('数据库出错!','错误');
end;
end;
//右键选择删除时,删除当前节点和它的所有后代
procedure TForm1.N2Click(Sender: TObject);
begin
if pNode(TestTree.Selected.Data).sItem = 'ITEM' then
begin
Application.MessageBox('您不能删除根节点!','对不起');
Exit;
end;
try
TestTable.FindKey( [ pNode(TestTree.Selected.Parent.Data).sItem ] );
TestTable.Edit;
TestTable.FieldByName('ChildNum').AsInteger := TestTable.FieldByName('ChildNum').AsInteger - 1;
TestTable.Post;
except
Application.MessageBox('数据库出错!','错误');
end;
DeleteNode(TestTree.Selected);
end;
procedure TForm1.DeleteNode(CurrentNode: TTreeNode);
var
i,nChildNum: Integer;
tChildNode: TTreeNode;
begin
nChildNum := CurrentNode.Count;
for i := 1 to nChildNum do
begin
tChildNode := CurrentNode.GetLastChild;
DeleteNode(tChildNode);
end;
try
TestTable.FindKey( [ pNode(CurrentNode.Data).sItem ] );
TestTable.Delete;
except
Application.MessageBox('数据库出错!','错误');
end;
TestTree.Items.Delete(CurrentNode);
end;
//保存当前节点的内容
procedure TForm1.Button1Click(Sender: TObject);
begin
try
TestTable.FindKey( [ pNode(TestTree.Selected.Data).sItem ] );
TestTable.Edit;
TestTable.FieldByName('Text').AsString := MemoTree.Text;
TestTable.Post;
except
Application.MessageBox('数据库出错!','错误');
end;
end;
//当更改节点名称时,同时修改数据库
procedure TForm1.TestTreeEdited(Sender: TObject; Node: TTreeNode;
var S: String);
begin
try
TestTable.FindKey( [ pNode(Node.Data).sItem ] );
TestTable.Edit;
TestTable.FieldByName('Name').AsString := S;
TestTable.Post;
except
Application.MessageBox('数据库出错!','错误');
end;
end;
procedure TForm1.TestTreeCustomDrawItem(Sender: TCustomTreeView;
Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
begin
if Node.Expanded = True then
Node.StateIndex := 1
else
Node.StateIndex :=2;
end;
end.