好的,我正在使用Embarcadero Delphi 2010.目前我在该文件中使用名为flib.mdb
的Access数据库文件,我创建了一个名为MCategory
的表,其中有4(4)列命名:codecategory
为文字和主键,parentcategory
为文字,category
为文字,notes
为文字。
对于数据库连接,我使用ADOConnection。对于查询,我使用ADOQuery。对于表格,我使用ADOTable。
因为代码是使用前缀自动生成的,但是对于示例我使用常规数字作为字符串。
只有一个ROOT:codecategory="0" // parentcategory="" // category="ROOT"
不允许添加另一个ROOT(具有空parentcategory的ROOT)
我的问题是如何重新屏蔽所有父类别,如下图所示?以及如何在DBGrid上查看它?
我应该使用递归吗?有没有简单的方法呢?
还请Delphi 2010中的源代码.... ^^
答案 0 :(得分:0)
您可以将数据集的所有记录转换为TStringList并对其进行排序。
接口部分中的声明:
TForm1=class(...)
RecordList:TStringList;
constructor Create(AOwner:TComponent);override;
destructor Destroy;override;
end;
TCategoryItem=class
public:
CategoryTitle:string;
Id,ParentId:Variant;
end;
在实施部分:
constructor TForm1.Create(AOwner: TComponent);
begin
inherited ;
RecordList:=TstringList.create(true); // use this code in FormCreate also
end;
destructor TForm1.Destroy;
begin
...
RecordList.Free;// use this code in FormDestory also
end;
procedure TForm1.AdoQuery1AfterOpen(DataSet:TDataSet);
var
Item,RootItem:TCategoryItem;
begin
DataSet.First;
DataSet.DisableControls;
try
(*add abstract root item to RecordList if needed
RootItem:=TCategoryItem.Create;
RootItem.CategoryTitle:='ROOT';
RecordList.AddObject('',RootItem);*)
while not DataSet.Eof do
begin
Item:=TCategoryItem.Create;
Item.CategoryTitle:=DataSet['Cateogory'];
Item.Id:=DataSet['CodeCategory'];
Item.ParentId:=DataSet['ParentCategory'];
RecordList.AddObject(VarToStr(Item.Id),Item);
DataSet.Next;
end;
finally
RecordList.Sort; // for use find(binary search)
DataSet.EnableControls;
DataSet.First;
end;
end;
procedure TForm1.OnGetFieldText(Sender: TField; var Text: string;
DisplayText: Boolean);
var
Idx:Integer;
ParentValue:Variant;
Item:TCategoryItem;
Texts:TStringList;
begin
ParentValue:=Sender.Value;
Texts:=TStringList.create;
try
while RecordList.Find(varToStr(ParentValue),Idx) do
begin
Item:=RecordList.Objects[Idx] as TCategoryItem;
Texts.Insert(0,Item.CategoryTitle);
ParentValue:=Item.ParentId;
end;
Texts.Delimiter:='>';
Text:=Texts.DelimitedText;
finally
Texts.Free;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
ADOQuery1.FieldByName('parentcategory').OnGetText := OnGetFieldText;
ADOQuery1.Refresh;
end;