chenby,你老兄会找地方呀!
创建树本身的算法是比较简单的,但我的程序中有许多管理方面的内容,
以下把与创建有关的代码贴出,没有整理,慢慢看吧。
TDBTreeView=class(TTreeView)
......
procedure TDBTreeView.OpenTree;
begin
FTryOpen:=True;
OpenTables;
Items.Clear;
try
InsertSubTree(CreateSubTreeNode(nil,FRootCaption,'',RootImageIndex),'');
FActive := True;
finally
FTempQuery.Close;
end;
end;
procedure TDBTreeView.InsertSubTree(ParentNode:TDBTreeNode; ParentCode:string);
var
i:integer;
begin
if GetChildRecords(FTempQuery,ParentCode) then
begin
CreateSubNodes(ParentNode,FTempQuery,IDFieldName,MasterFlag);
//若一次全部建立,则递归:
for i:=0 to ParentNode.Count-1 do
InsertSubTree(ParentNode.Item, CodeOfNode(ParentNode.Item));
//否则,在OnChange或OnClick事件中调用此方法
end;
end;
procedure TDBTreeView.CreateSubNodes(ParentNode: TDBTreeNode; DataSet:TDBDataSet; IDField:string; NodeType:integer);
begin
DataSet.First;
while not DataSet.Eof do
begin
CreateSubTreeNode( ParentNode,
TakeNodeLabel(DataSet,NodeType),
DataSet.FieldByName(IDField).AsString,
NodeType);
DataSet.Next;
end;
end;
function TDBTreeView.CreateSubTreeNode(ParentNode:TDBTreeNode; ACaption,ACode:string; NodeFlag:integer):TDBTreeNode;
begin
Result:=Items.AddChild(ParentNode,ACaption) as TDBTreeNode;
Result.NodeFlag := NodeFlag;
Result.SelectedIndex := NodeFlag+1;
SetCodeOnNode(ACode,Result);
end;
function TDBTreeView.GetChildRecords(Query:TQuery; ParentCode:string):boolean;
const
StmtFmt='select * from %s where %s';
OrderStmt='order by %s';
CondFmt1='%s IS NULL or (%0:s='''')';
CondFmt2='(%s=''%s'')';
var
StmtCond:string;
begin
if not CanOpenTree then
begin
Result:=False;
Exit;
end;
Query.Close;
if Assigned(FOnGetChildrenCondition) then
StmtCond:=FOnGetChildrenCondition(Self,ParentCode)
else
begin
if ParentCode='' then
StmtCond:=Format(CondFmt1,[FParentIDFieldName])
else
StmtCond:=Format(CondFmt2,[FParentIDFieldName,ParentCode]);
end;
Query.SQL.Clear;
Query.SQL.Add(Format(StmtFmt,[FTableName,StmtCond]));
if OrderFieldName<>'' then
Query.SQL.Add(Format(OrderStmt,[OrderFieldName]));
Query.Open;
Result:=True;
end;