Handling Bitmap Column in FNCDataGrid

How can I dynamically set a bitmap in FNCDataGrid column. Basing on your example I tried:

procedure TForm1.TMSFNCDataGrid1GetCellLayout(Sender: TObject;
  ACell: TTMSFNCDataGridCell);
var
  o: Integer;
begin
  if not Assigned(TMSFNCDataGridDatabaseAdapter1) or not TMSFNCDataGridDatabaseAdapter1.CheckDataSet then
    Exit;

  o := TMSFNCDataGridDatabaseAdapter1.DataLink.ActiveRecord;
  try
    if TMSFNCDataGridDatabaseAdapter1.SetActiveRecord(ACell.Row) then
    begin
      if TMSFNCDataGridDatabaseAdapter1.ColumnAtField['Category'].Field.AsString = 'Shark' then
		TMSFNCDataGrid1.AddBitmap(nCol, nRow, 'BitmapName');
    end;
  finally
    TMSFNCDataGridDatabaseAdapter1.DataLink.ActiveRecord := o;
  end;
end;

It doesn't work, after a few seconds application is closing. AddBitmap I'm using in FNCGrid in FNCGrid1GetCellLayout, and there it's working.

Can you give me a hint? Please

The application closes because AddBitmap modifies the grid during OnGetCellLayout. Internally it starts/ends an update cycle, which recalculates the grid and invokes OnGetCellLayout again—causing recursive recalculation.

Configure the column as a bitmap column once, then customize the temporary cell through OnGetCellProperties:

procedure TForm1.FormCreate(Sender: TObject);
begin
  TMSFNCDataGrid1.BitmapContainer := TMSFNCBitmapContainer1;

  // Execute after the database-adapter columns have been created.
  TMSFNCDataGrid1.Columns[nCol].&Type := gcitBitmap;
  TMSFNCDataGrid1.Columns[nCol].TypeRange := gcirNormal;
end;

procedure TForm1.TMSFNCDataGrid1GetCellProperties(
  Sender: TObject; ACell: TTMSFNCDataGridCell);
var
  LOldRecord: Integer;
  LBitmapCell: TTMSFNCDataGridBitmapCell;
begin
  if (ACell.Column <> nCol) or
     not (ACell is TTMSFNCDataGridBitmapCell) or
     not Assigned(TMSFNCDataGridDatabaseAdapter1) or
     not TMSFNCDataGridDatabaseAdapter1.CheckDataSet then
    Exit;

  LBitmapCell := TTMSFNCDataGridBitmapCell(ACell);

  // Cells are pooled/reused, so always reset the value.
  LBitmapCell.BitmapName := '';

  LOldRecord := TMSFNCDataGridDatabaseAdapter1.DataLink.ActiveRecord;
  try
    if TMSFNCDataGridDatabaseAdapter1.SetActiveRecord(ACell.Row) and
       (TMSFNCDataGridDatabaseAdapter1
          .ColumnAtField['Category'].Field.AsString = 'Shark') then
      LBitmapCell.BitmapName := 'BitmapName';
  finally
    TMSFNCDataGridDatabaseAdapter1.DataLink.ActiveRecord := LOldRecord;
  end;
end;

The important distinction is:

  • OnGetCellLayout: modify only ACell.Layout.
  • OnGetCellProperties: modify properties such as BitmapName.
  • AddBitmap: call outside rendering events when persistent grid data should change.

Thanks a lot, everything is clear now.