已经寄出.可能不能完全说明问题.
曹的答案虽然正确,但只能处理两层,不能处理任意层,因为没有递归.
李维的方法可行,但代价太大,但深入一层需要建立一个新的数据集.
我的办法则要简洁一些.
TSchoolObject = class(TObject)
private
FOwner: TSchoolBranchObject;
FID: Integer;
FName: string;
FLevel: Integer;
FValid, FSelected: Boolean;
procedure SetName(const Value: string);
procedure SetValid(Value: Boolean);
procedure SetSelected(Value: Boolean);
function GetIndexOf: Integer;
protected
procedure BeginReport(AView: TRichView); virtual;
procedure EndReport(AView: TRichView); virtual;
public
constructor Create(AOwner: TSchoolBranchObject; AID: Integer;
const AName: string; ALevel: Integer; AValid: Boolean);
function ListItem(AView: TExtListView): TListItem; virtual; //列出本项
procedure ReportItem(AView: TRichView); virtual; //简单报告
procedure DetailItem(AView: TRichView); virtual; //详细报告
property ID: Integer read FID;
property Name: string read FName write SetName;
property Owner: TSchoolBranchObject read FOwner;
property LevelIndex: Integer read FLevel;
property Valid: Boolean read FValid write SetValid;
property Selected: Boolean read FSelected write SetSelected;
property IndexOf: Integer read GetIndexOf;
end;
TSchoolBranchObject = class(TSchoolObject)
private
FChildren: TList;
FNode: TTreeNode;
FSelCount: Integer;
function GetCount: Integer;
function GetItems(Index: Integer): TSchoolObject;
protected
procedure CreateHeader(AView: TExtListView); virtual; abstract;
function GetPathName: string; virtual; abstract;
public
constructor Create(AOwner: TSchoolBranchObject; AID: Integer;
const AName: string; ALevel: Integer; AValid: Boolean);
destructor Destroy; override;
procedure Add(AObj: TSchoolObject);
procedure Delete(Index: Integer);
procedure Clear;
procedure ClearSelected;
procedure IncSelected;
procedure DecSelected;
function SeekChild(AID: Integer): TSchoolObject;
function CreateNode(ParentNode: TTreeNode): TTreeNode; virtual; //生成本结点
procedure CreateNodes; virtual; //生成子结点
function CreateView(AView: TExtListView): string; virtual; //生成列表
function IndexOf(AObject: TSchoolObject): Integer;
property Count: Integer read GetCount;
property Items[index: Integer]: TSchoolObject read GetItems; default;
property Node: TTreeNode read FNode write FNode;
property SelCount: Integer read FSelCount;
end;
....
//TSchoolObject 对象
constructor TSchoolObject.Create(AOwner: TSchoolBranchObject; AID: Integer;
const AName: string; ALevel: Integer; AValid: Boolean);
begin
FOwner := AOwner;
FID := AID;
FName := AName;
FLevel := ALevel;
FValid := AValid;
FSelected := False;
end;
procedure TSchoolObject.SetName(const Value: string);
begin
if FName <> Value then
FName := Value;
end;
procedure TSchoolObject.SetValid(Value: Boolean);
begin
if FValid <> Value then
FValid := Value;
end;
procedure TSchoolObject.SetSelected(Value: Boolean);
begin
if FSelected <> Value then begin
FSelected := Value;
if FSelected then
FOwner.IncSelected
else
FOwner.DecSelected;
end;
end;
function TSchoolObject.GetIndexOf: Integer;
begin
Result := FOwner.IndexOf(Self);
end;
procedure TSchoolObject.BeginReport(AView: TRichView);
begin
AView.Clear;
AView.AddFromNewLine(' ', 1);
AView.AddFromNewLine(FOwner.Name, 1);
AView.AddGradBreak;
AView.AddFromNewLine(' ', 0);
AView.AddFromNewLine(Name, 1);
end;
procedure TSchoolObject.EndReport(AView: TRichView);
begin
AView.FormatIt;
AView.Refresh;
end;
function TSchoolObject.ListItem(AView: TExtListView): TListItem;
begin
Result := AView.Items.Add;
with Result do begin
Caption := Name;
ImageIndex := LevelIndex;
Data := Self;
end;
end;
procedure TSchoolObject.ReportItem(AView: TRichView);
begin
BeginReport(AView);
EndReport(AView);
end;
procedure TSchoolObject.DetailItem(AView: TRichView);
begin
AView.FormatIt;
AView.Refresh;
end;
//TSchoolBranchObject 对象
constructor TSchoolBranchObject.Create(AOwner: TSchoolBranchObject;
AID: Integer; const AName: string; ALevel: Integer; AValid: Boolean);
begin
inherited Create(AOwner, AID, AName, ALevel, AValid);
FChildren := TList.Create;
FSelCount := 0;
end;
destructor TSchoolBranchObject.Destroy;
begin
Clear;
FChildren.Free;
inherited Destroy;
end;
function TSchoolBranchObject.GetCount: Integer;
begin
Result := FChildren.Count;
end;
function TSchoolBranchObject.GetItems(Index: Integer): TSchoolObject;
begin
Result := FChildren[Index];
end;
procedure TSchoolBranchObject.Add(AObj: TSchoolObject);
begin
FChildren.Add(AObj);
end;
procedure TSchoolBranchObject.Delete(Index: Integer);
begin
TSchoolObject(FChildren[Index]).Free;
FChildren.Delete(Index);
end;
procedure TSchoolBranchObject.Clear;
begin
while FChildren.Count > 0 do
Delete(FChildren.Count - 1);
end;
procedure TSchoolBranchObject.ClearSelected;
var
I: Integer;
begin
for I := 0 to Count - 1 do
GetItems(I).Selected := False;
end;
procedure TSchoolBranchObject.IncSelected;
begin
Inc(FSelCount);
end;
procedure TSchoolBranchObject.DecSelected;
begin
Dec(FSelCount);
end;
function TSchoolBranchObject.SeekChild(AID: Integer): TSchoolObject;
var
I: Integer;
begin
Result := nil;
for I := 0 to Count - 1 do
if GetItems(I).ID = AID then begin
Result := GetItems(I);
Break;
end;
end;
function TSchoolBranchObject.CreateNode(ParentNode: TTreeNode): TTreeNode;
begin
Result := TTreeView(ParentNode.TreeView).Items.AddChildObject(ParentNode,
Name, Self);
Result.ImageIndex := LevelIndex;
FNode := Result;
CreateNodes;
end;
procedure TSchoolBranchObject.CreateNodes;
var
I: Integer;
begin
if Count > 0 then
if GetItems(0) is TSchoolBranchObject then
for I := 0 to Count - 1 do
TSchoolBranchObject(GetItems(I)).CreateNode(FNode);
end;
function TSchoolBranchObject.CreateView(AView: TExtListView): string;
var
I: Integer;
begin
Result := GetPathName;
CreateHeader(AView);
AView.Items.Clear;
for I := 0 to Count - 1 do
GetItems(I).ListItem(AView);
end;
function TSchoolBranchObject.IndexOf(AObject: TSchoolObject): Integer;
begin
Result := FChildren.IndexOf(AObject);
end;
如果以上代码前言不搭后语也是正常的,这是从我的单元中断章取义.
使用时一次将数据集打开,按顺序填入,然后用以下代码直接建立树:
ATreeView.Items.Clear;
Node := ATreeView.Items.AddChildObject(nil, Caption1, Self);
CreateNodes;