TTMSFNCDataGrid cell graphics

What is the best way to dynamically update an image in a cell before the cell is drawn?
In the OnBeforeDrawCell event I can see there is AGraphics.Bitmap property but I am not sure if I should manage the lifecycle of this or if there is a recommended way to use this.

This is the code so far, but it obviously does not work because AGraphics.Bitmap is not created.

Side note - it would be nice if ACell had direct access to the Cells Object rather than having to get it from the parent (Fgrid.Objects[ACell.Column, ACell.Row]).

procedure TFixtureGroup.gridBeforeDrawCell(Sender: TObject;
  AGraphics: TTMSFNCGraphics; ACell: TTMSFNCDataGridCell;
  var ACanDraw: Boolean);
begin
  inherited;
  if ACell.Row > 0 then
  begin
    // Necessary because banding does not AdaptToStyle
    if ACell.Row mod 2 = 0 then
      AGraphics.Fill.Color := $FF303030
    else
      AGraphics.Fill.Color := $FF232323;

    if ACell.Column > 2 then
    begin
      var ctrl := TAttControl(Fgrid.Objects[ACell.Column, ACell.Row]);
      if assigned(ctrl) then
      begin
        AGraphics.Font.Color := ctrl.TextColour;
        if ctrl.AttType = atDynamicColour then
        begin
          // draw a circle representing the dynamic colour of the attribute
          var col := ctrl.GetDynamicColour;
          if col > 0 then
          begin
            // Make the bitmap square based on cell height
            AGraphics.Bitmap.Width  := Round(ACell.Height);
            AGraphics.Bitmap.Height := Round(ACell.Height);
            AGraphics.Bitmap.Clear(TAlphaColorRec.Null);
            // Create a rectangle inset by 2 px
            var R := TRectF.Create(2, 2, AGraphics.Bitmap.Width - 2, AGraphics.Bitmap.Height - 2);
            // Draw a filled circle
            AGraphics.Bitmap.Canvas.Fill.Color := col;
            AGraphics.Bitmap.Canvas.FillEllipse(R, 1);
          end;
        end
        else if ctrl.AttType = atGeneric then
        begin

        end;
      end;
    end;
  end;
end;

Hi,

To access the object, you need to go through the Data property.

var
  o: TObject;
begin
  if IsExtendedCell(ACell.Data) then
  begin
    o := AsExtendedCell(ACell.Data).&Object;
  end;

There are several approaches

  1. Change the assigned bitmap in the OnGetCellProperties (like your initial approach)
    Sample1.zip (83.7 KB)

  2. Direct custom cell drawing
    TTMSFNCDataGrid - TMS FNC UI Pack

  3. Add a custom cell class
    CustomCellClass.zip (82.4 KB)


Option 1) dynamically changing the contents of the bitmap for each cell while it's being configured/rendered can be slow

Option 2) and 3) should be the fast and better option

1 Like

The custom cell class is very interesting but in the end I could not think how it really helped with the implementation I am doing. Although I am sure there is a power to it that I cannot currently see.
I ended up using the custom drawing. This is how I do it in my VCL implementation.

1 Like

Thanks for the feedback Martin

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.