Search code examples
c++delphidbgridtdbgrid

Delphi / C++ Builder - Set active/selected row color in TDBGrid


I want to set the background color of the active/selected row in a TDBGrid control.

Using the OnDrawColumnCell event:

1) The following code will work if DBGrid has the option dgMultiSelect, if not, nothing happens:

if ( grid->SelectedRows->CurrentRowSelected ) {
    grid->Canvas->Brush->Color = clBlue;
} 

2) The following code will work if DBGrid has the option dgRowSelect, if not, only the selected CELL, not the entire row, will be colored:

if ( State.Contains(gdSelected) ) {
    grid->Canvas->Brush->Color = clBlue;
} 

How could I color the entire active/selected row without using dgRowSelect or dgMultiSelect?


Solution

  • From OnDrawColumnCell:

    An OnDrawColumnCell event handler can call the DefaultDrawColumnCell method to instruct the data-aware grid to write the data value in the cell.

    Use DefaultDrawColumnCell like this. This is Delphi code but you may convert it easy.

    procedure TForm1.DBGridDrawColumnCell(Sender: TObject;const Rect: TRect; 
    DataCol: Integer; Column: TColumnEh;State: TGridDrawState);
    begin
    .....    
      DBGrid.Canvas.Brush.Color := clBlue;
      DBGrid.DefaultDrawColumnCell(Rect,DataCol,Column,State);
    ....
    

    Update

    How to paint the DBGrid active row, without setting dgRowSelect or dgMultiSelect.

    1. We need to get the top position of current row.

    Define a class that inheritant of TDBGrid to make CellRect, Col and Row public:

    type
      TMyDBGrid = class(TDBGrid)
      public
        function CellRect(ACol, ARow: Longint): TRect;
        property Col;
        property Row;
      end;
    
    function TMyDBGrid.CellRect(ACol, ARow: Longint): TRect;
    begin
      Result := inherited CellRect(ACol, ARow);
    end;
    

    Now we can check the top of current cell in OnDrawColumnCell event :

    procedure TMainForm.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
      DataCol: Integer; Column: TColumn; State: TGridDrawState);
    
    var Col,Row : Integer;
    begin
      col := TMyDbGrid(DBGrid1).Col;
      row := TMyDbGrid(DBGrid1).Row;
      if (Rect.Top = TMyDBGrid(DBGrid1).CellRect(Col,Row).Top) and
                       (not (gdFocused in State) or not Focused) then
        DBGrid1.Canvas.Brush.Color := clBlue;
    
      DBGrid1.DefaultDrawColumnCell(Rect,DataCol,Column,State);
     end;