我做了一个DBTreeView控件,只要有以下字段即可
fid //自动增加类型
fPid //父ID
fdisplayname //字段显示名称
源代码如下:
{
Author: Deityfox
Email: Deityfox@163.com
Homepage: http://www.pfans.net/
QQ: 58193693
Date: 2002/11/23
CopyRight(C) 2001-2002 FoxStuio
}
unit DBTreeViewEx;
interface
uses
Windows, Messages, SysUtils, Classes, Controls,forms, ComCtrls,DB;
type
TDBTreeViewEx = class(TTreeView)
private
{ Private declarations }
FParentField:TIntegerField;
FChildField:TIntegerField;
FDisplayField:TStringField;
FDataLink:TDataLink;
FActive:Boolean;
//SubItems:TStrings;
FOnChanged: TNotifyEvent;
Procedure SetParentField(const aField:TIntegerField);
Procedure SetChildField(const aField:TIntegerField);
Procedure SetDisplayField(const aField:TStringField);
Function GetDataSource:TDataSource;
Procedure SetDataSource(ads:TDataSource);
Procedure FillContents(aParent:String;Node:TTreeNode);
Procedure SetActive(const aActive:Boolean);
protected
procedure Collapse(Node: TTreeNode);override;
procedure Expand(Node: TTreeNode);override;
{ Protected declarations }
public
Constructor Create(Owner:TComponent);Override;
Destructor Destroy;Override;
{ Public declarations }
published
Property ParentField:TIntegerField Read FParentField Write SetParentField;
Property ChildField:TIntegerField Read FChildField Write SetChildField;
Property DisplayField:TStringField Read FDisplayField Write SetDisplayField;
Property DataSource:TDataSource Read GetDataSource Write SetDataSource;
Property Active:Boolean Read FActive Write SetActive;
Property OnChanged:TNotifyEvent read FOnChanged write FOnChanged;
{ Published declarations }
end;
procedure Register;
implementation
Constructor TDBTreeViewEx.Create(Owner:TComponent);
Var I:Integer;
begin
Inherited Create(Owner);
FDataLink:=TDataLink.Create;
FDataLink.DataSource:=nil;
FParentField:=nil;
FChildField:=nil;
FDisplayField:=nil;
Active:=False;
if owner is TForm then
begin
for I:=0 to TForm(owner).ComponentCount-1 do
begin
if TForm(owner).Components is TImageList then
begin
Images:=TForm(Owner).Components as TImageList;
break;
end;
end;
end;
end;
Function TDBTreeViewEx.GetDataSource:TDataSource;
begin
Result:=FDataLink.DataSource;
end;
Procedure TDBTreeViewEx.SetDataSource(ads:TDataSource);
begin
if ads<>FDataLink.DataSource then
FDataLink.DataSource:=ads;
end;
Procedure TDBTreeViewEx.SetParentField(const aField:TIntegerField);
begin
if aField<>FParentField then FParentField:=aField;
if (FParentField<>nil) and (FChildField<>nil) and (FDisplayField<>nil)
and (Assigned(FDataLink.DataSource)) and Assigned(FDataLink.DataSource.DataSet) then
begin
Items.Clear;
FillContents('0',Nil);
FActive:=True;
end;
end;
Procedure TDBTreeViewEx.SetChildField(const aField:TIntegerField);
begin
if aField<>FChildField then FChildField:=aField;
if (FParentField<>nil) and (FChildField<>nil) and (FDisplayField<>nil)
and (Assigned(FDataLink.DataSource)) and Assigned(FDataLink.DataSource.DataSet) then
begin
Items.Clear;
FillContents('0',Nil);
FActive:=True;
end;
end;
Procedure TDBTreeViewEx.SetDisplayField(const aField:TStringField);
begin
if aField<>FDisplayField then FDisplayField:=aField;
if (FParentField<>nil) and (FChildField<>nil) and (FDisplayField<>nil)
and (Assigned(FDataLink.DataSource)) and Assigned(FDataLink.DataSource.DataSet) then
begin
Items.Clear;
FillContents('0',Nil);
Active:=True;
end;
end;
Procedure TDBTreeViewEx.FillContents(aParent:String;Node:TTreeNode);
Var
aNode:TTreeNode;
ChildList:TStrings;
DisplayList:TStrings;
I:Integer;
begin
ChildList:=TStringList.Create;
DisplayList:=TStringList.Create;
With DataSource.DataSet do
begin
Filtered:=False;
Filter:=FParentField.FieldName+'='+aParent;
Filtered:=True;
First;
While Not Eof do
begin
ChildList.Add(FChildField.AsString);
DisplayList.Add(FDisplayField.AsString);
Next;
end;
For I:=0 to ChildList.Count-1 do
begin
aNode:=Items.AddChildObject(Node,DisplayList.Strings,pointer(strtoint(ChildList.Strings)));
aNode.ImageIndex:=1;
FillContents(ChildList.Strings,aNode);
end;
Filtered:=False;
ChildList.Free;
DisplayList.Free;
end;
Selected:=Items[0];
end;
Procedure TDBTreeViewEx.SetActive(const aActive:Boolean);
begin
if FActive=aActive then Exit;
if Not aActive then
begin
Items.Clear;
FActive:=False;
end else
begin
if (FParentField<>nil) and (FChildField<>nil) and (FDisplayField<>nil)
and (Assigned(FDataLink.DataSource)) and Assigned(FDataLink.DataSource.DataSet) then
begin
Items.Clear;
FillContents('0',Nil);
FActive:=True;
end;
end;
if Assigned(OnChanged) then OnChanged(Self);
end;
procedure TDBTreeViewEX.Collapse(Node: TTreeNode);
begin
Node.ImageIndex:=1;
inherited;
end;
procedure TDBTreeViewEx.Expand(Node: TTreeNode);
begin
Node.ImageIndex:=2;
inherited;
end;
procedure Register;
begin
RegisterComponents('FoxStudio', [TDBTreeViewEx]);
end;
destructor TDBTreeViewEx.Destroy;
begin
FDataLink.Free;
inherited Destroy;
end;
end.