Marc Guillot
Marc Guillot

Reputation: 6465

I can't set the text formatting on my own derivative of a TDBGrid

I'm creating a derivative of the TDBGrid, and I want to implement a nicer way to define its text formatting, something similar to the GetContentStyle of the QuantumGrid.

The problem is that the DBGrid ignores the font and colors that my new event sets on its Canvas.

type TSetCellStyle = procedure(const Sender: TObject; const AColumn: TColumn; const ARow: TDataset; const AField: TField; const State: TGridDrawState; var TextFont: TFont; var BackgroundColor: TColor) of object;

TMyDBGrid = class(TDBGrid)
  private
    FSetCellStyle: TSetCellStyle;
  protected
    procedure DrawColumnCell(const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState); override;
  published
    property OnSetCellstyle: TSetCellStyle read FSetCellStyle write FSetCellStyle;
  ...
  ...

implementation
  procedure TMyDBGrid.DrawColumnCell(const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState); 
  begin
    BeginUpdate;
    Canvas.Lock; // Prevents other threads from drawing on the canvas.

    if Assigned(FSetCellStyle) then begin
      var TextFont: TFont;
      var BackgroundColor: TColor;
      TextFont := Canvas.Font;
      BackgroundColor := Canvas.Brush.Color;
      FSetCellStyle(Self, Column, Self.DataSource.DataSet, Self.DataSource.DataSet.FindField(Column.FieldName), State, TextFont, BackgroundColor);
      Canvas.Font := TextFont;
      Canvas.Brush.Color := BackgroundColor;
    end;

    Canvas.Unlock;
    inherited DrawColumnCell(Rect, DataCol, Column, State);
    EndUpdate;     
  end;

This is an exemple of how the application uses the new event to customize the formatting of a grid:

procedure TFInspira.GridInspiraSetCellStyle(const Sender: TObject; const AColumn: TColumn; const ARow: TDataSet; const AField: TField; const State: TGridDrawState; var TextFont: TFont; var BackgroundColor: TColor);
begin
  if (AColumn.FieldName = 'ReferenciaGrup') and (ARow.FieldByName('PrimerDeGrup').AsBoolean) then begin
    BackgroundColor := clYellow;
  end;
  if ARow.FieldByName('Selected').AsBoolean then begin
    TextFont.Style := TextFont.Style + [fsItalic];
  end;
end;

I can debug my grid and see that the overriden DrawColumnCell sets the canvas in yellow and italic for some cells, but the Grid never shows them. Looks like the call to inherit DrawColumnCell resets the Canvas' formats.

If I can't hook my formatting event in DrawColumnCell where can I do so ?.

Thank you.

Upvotes: 1

Views: 210

Answers (1)

MartynA
MartynA

Reputation: 30745

I think that your DrawColumnCell is just missing a call to DefaultDrawDataCell to get the grid to actually draw the cell. F.i.in my answer to your other q,

procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
  DataCol: Integer; Column: TColumn; State: TGridDrawState);
var
  AGrid : TDBGrid;
begin
  AGrid := (Sender as TDBGrid);

  if Odd(AGrid.RowBeingDrawn) then begin
     AGrid.Canvas.Brush.Color := clGreen;
  end;
  AGrid.DefaultDrawDataCell(Rect, Column.Field, State);

end;

Obviously, this paints the cells of alternate rows green.

I've used the interposer class of my other answer just so I could refer to the added RowBeingDrawn property, but code similar to the above will work just as well with the standard TDBGrid (provided its DefaultDrawing property is set to True).

Upvotes: 2

Related Questions