FNCGrid +FNCGridDatabaseAdapter set row fill color

Delphi Tokyo (10.2.3), FNC UI Pack 2.5.2.1, FMX project
I use TTMSFNCGrid with TTMSFNCGridDatabaseAdapter. Grid shows the results of the query.
I want to set fill color for full row depending on value of field in the query.
How can I do it? 
Or may be
How can I get field value in the event OnGetCellLayout?

Hi,


You can use the OnGetCellLayout event and use the following code to access the field:


procedure TForm57.TMSFNCGrid1GetCellLayout(Sender: TObject; ACol, ARow: Integer;
  ALayout: TTMSFNCGridCellLayout; ACellState: TTMSFNCGridCellState);
var
  s: string;
  c: Integer;
  f: TField;
begin
  c := ACol - TMSFNCGrid1.FixedColumns;
  if TMSFNCGridDatabaseAdapter1.Active and (c >= 0) and (c <= TMSFNCGridDatabaseAdapter1.Columns.Count - 1) then
  begin
    f := TMSFNCGridDatabaseAdapter1.FieldAtColumn[ACol - TMSFNCGrid1.FixedColumns];
    if Assigned(f) then
    begin
      //
    end;
  end;
end;

Thanks for your quick answer. Unfortunally it doesn't work because of there is no synchronization between parameter ARow and TMSFNCGridDatabaseAdapter.DataLink.DataSet during the event OnGetCellLayout.
I can get current value of the field of TDataSet only for row of the SELECTED Cell while OnGetCellLayout event is triggered for all grid cells visible in the window.

Hi,


You can accomplish this by setting the ActiveRecord within the buffer to the current row. The code below demonstrates this.


type
  TTMSFNCGridDatabaseAdapterOpen = class(TTMSFNCGridDatabaseAdapter);


procedure TForm1.TMSFNCGrid1GetCellLayout(Sender: TObject; ACol,
  ARow: Integer; ALayout: TTMSFNCGridCellLayout;
  ACellState: TTMSFNCGridCellState);
var
  c: Integer;
  f: TField;
  o: Integer;
  s: string;


  procedure SetActiveRecord;
  var
    ro, tp, off, rs: Integer;
  begin
    ro := TTMSFNCGridDatabaseAdapterOpen(TMSFNCGridDatabaseAdapter1).GetRecordNo;
    tp := TMSFNCGridDatabaseAdapter1.DataLink.ActiveRecord + TMSFNCGrid1.TopRow - TMSFNCGrid1.FixedRows;
    off := tp - (ro - 1);
    rs := ARow - TMSFNCGrid1.TopRow + off;
    TMSFNCGridDatabaseAdapter1.DataLink.ActiveRecord := rs
  end;


begin
  if not TMSFNCGridDatabaseAdapter1.CheckDataSet then
    Exit;


  c := ACol - TMSFNCGrid1.FixedColumns;
  if TMSFNCGridDatabaseAdapter1.Active and (ARow >= TMSFNCGrid1.FixedRows) and (c >= 0) and (c <= TMSFNCGridDatabaseAdapter1.Columns.Count - 1) then
  begin
    f := TMSFNCGridDatabaseAdapter1.FieldAtColumn[c];
    if Assigned(f) then
    begin
      o := TMSFNCGridDatabaseAdapter1.DataLink.ActiveRecord;
      try
        SetActiveRecord;


        s := f.AsString;
        if s.StartsWith('BM') then
          ALayout.Fill.Color := gcRed;


      finally
        TMSFNCGridDatabaseAdapter1.DataLink.ActiveRecord := o;
      end;
    end;
  end;
end;

1 Like
Thank you very much. This solved the problem. 
It seems to me that such a method should be included in the public section of the adapter (?), since it is not completely obvious.