Search code examples
delphifiremonkeytstringgridfdmemtable

Delphi 10.4 - Sort Memtable by clicking Stringgrid Header


I feel like an idiot because my question seams so simple but I don't get it done :D

My Settings is that:

One Dataset (Memtable), One Stringgrid. The Grid is bind via live Bindungs.

I would like to sort my Columns by clicking on the GridHeader. In the OnHeaderClick Event I get an tColumn Object. I only can read the Column.Header String, but I changed the Text from the Header to a more speakable Text. When I put Column.header into Memtable.Indexfieldsname Memtable says that field does not exist, what is right, but I don't know how to get the right Fieldname from the column.


Solution

  • What you want is quite straightforward to do. In the example below, which uses the demo data from the Biolife demo, I've linked the StringgRid to the FDMemTable entirely by binding objects created in code so that there is no doubt about any of the binding steps or binding properties, nor the method used to establish the bindings.

    procedure TForm2.FormCreate(Sender: TObject);
    var
      BindSourceDB1 : TBindSourceDB;
      LinkGridToDataSourceBindSourceDB1 : TLinkGridToDataSource;
    begin
      //  Note :  You need to load FDMemTable1 at design time from the sample Biolife.Fds datafile
    
      //  The following code creates a TBindSourceDB which Live-Binds FDMemTable1
      //  to StringGrid1
      //
      //  As a result, the column header texts will be the fieldnames of  FDMemTable1's fields
      //  However, the code that determines the column on which to sort the StringGrid does not depend
      //  on this
    
      BindSourceDB1 := TBindSourceDB.Create(Self);
      BindSourceDB1.DataSet := FDMemTable1;
    
      LinkGridToDataSourceBindSourceDB1 := TLinkGridToDataSource.Create(Self);
      LinkGridToDataSourceBindSourceDB1.DataSource := BindSourceDB1;
      LinkGridToDataSourceBindSourceDB1.GridControl := StringGrid1;
    
    end;
    
    procedure TForm2.StringGrid1HeaderClick(Column: TColumn);
    
    //  Sorts the STringGrid on the column whose header has been clicked
    
    var
      ColIndex,
      FieldIndex : Integer;
      AFieldName : String;
    begin
    
      ColIndex := Column.Index;
      FieldIndex := ColIndex;
    
      AFieldName := FDMemTable1.Fields[FieldIndex].FieldName;
      Caption := AFieldName;
    
      //  Should check here that the the field is a sortable one and not a blob like a graphic field
    
      FDMemTable1.IndexFieldNames := AFieldName;
    end;
    

    Note that this answer assumes that there is a one-for-one correspondence between grid columns and fields of the bound dataset, which will usually be the case for bindings created using the default methods in the IDE. However, Live Binding is sophisticated enough to support situations where this correspondence does not exist, and in those circumstances it should not be assumed that the method in this answer will work.