Search code examples
delphigridfiremonkey

FMX grid header lines color


I'm looking for a way to change the color of the lines in the header of an FMX grid. I have the following code to change the color of the lines in the grid itself, using an interposer:

type
  TStringGrid = class(FMX.Grid.TStringGrid)
  protected
    procedure ApplyStyle; override;
  end;

  TForm1 = class(TForm)
    StringGrid1: TStringGrid;
    StringColumn1: TStringColumn;
    StringColumn2: TStringColumn;
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

{ TStringGrid }

procedure TStringGrid.ApplyStyle;
var
  LLineFill: TBrushObject;
begin
  if FindStyleResource<TBrushObject>('LineFill', LLineFill) then
    LLineFill.Brush.Color := TAlphaColorRec.Orange;
  inherited;
end;

Which results in this:

enter image description here

But as can be seen, that just changes the color of the grid lines, not the header lines (which are still grey). Someone else suggested modifying the headeritemstyle (in code or at design-time) however that's a TButtonStyleObject, so there doesn't seem to be any relevant properties for that.

Any suggestions?


Solution

  • The style engine seems to neglect the headers totally (up until and including Delphi 10.4 CE, I don't know about later versions). But you can of course draw the header yourself. However, if your application supports several different styles, and you want to adapt your header drawing to currently selected style, it may become quite involved with different colors etc.

    Also you don't need to subclass the grid in order to use a style, for those parts of the grid that the style supports. Just select the grid, right click on it with the mouse and select "Edit custom style". The selected style will become a part of your form.

    Anyway, to answer your question, use the OnDrawColumnHeader() event as follows.

    procedure TForm4.StringGrid1DrawColumnHeader(Sender: TObject;
      const Canvas: TCanvas; const Column: TColumn; const Bounds: TRectF);
    var
      ABrush: TStrokeBrush;
      ARectF: TRectF;
    begin
      // fill
      Canvas.Fill.Color := TAlphaColorRec.Lavender;
      Canvas.FillRect(Bounds, 0, 0, [], 1);
    
      // draw rect, actually only bottom and right side of current header cell
      ABrush := TStrokeBrush.Create( TBrushKind.Solid , TAlphaColorRec.Red);
      try
        Canvas.DrawRectSides(Bounds, 0, 0, [], 1, [TSide.Bottom, TSide.Right], ABrush, TCornerType.Round);
    
        // Draw header text
        ARectF := Bounds;
        ARectF.Left := ARectF.Left + 4;
        Canvas.Font.Size := 15;
        Canvas.Fill.Color := TAlphaColorRec.Black;
        Canvas.FillText(ARectF, Column.Header , False, 1, [] , TTextAlign.Leading);
      finally
        ABrush.Free;
      end;
    end;
    

    I used TAlphaColorRec.Lavender as fill color and TAlphaColorRec.Red as line color for the header cells.

    And the result looks like this:

    enter image description here