Search code examples
delphiparentdbgridtadoquerytadotable

how to show parent category in delphi 2010?


OK, I'm using Embarcadero Delphi 2010. Currently I'm using an Access database file named flib.mdb within that file, I make a table named MCategory which has 4 (four) columns named: codecategory as Text and Primary Key, parentcategory as Text, category as Text, notes as Text.

For the Database connection, I use ADOConnection. For the query I use ADOQuery. For the table I use ADOTable.

For the code is auto generated with prefix, but for the example I use regular number as string.

There is only one ROOT : codecategory="0" // parentcategory="" // category="ROOT" not allowed to add another ROOT ( the one with empty parentcategory )

My question is how to remasking all of the parentcategory like the picture below ? And how to view it on DBGrid ?

parent category masking

Should I use recursive ? Is there any simple method to do so ?

And also source code in Delphi 2010 please.... ^^


Solution

  • You can convert all record of dataset to TStringList and Sorting it.

    in interface section declare this :

    TForm1=class(...)
      RecordList:TStringList;
      constructor Create(AOwner:TComponent);override;
     destructor Destroy;override; 
    
    end;
    TCategoryItem=class
    public:
       CategoryTitle:string;
       Id,ParentId:Variant;
    end;
    

    in implementation section :

    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;