How do I do a proper owner-draw of Full Row Selected TDBGrid when TDBGrid.DefaultDrawing is false?
Asked Answered
J

2

6

When you have a TDBGrid, full row selection, and always show selection, even when not focused, and you want to fully owner-draw it, you have a choice of a deprecated event OnDrawDataCell , and a new event DrawColumnCell, I chose the latter and try this:

procedure TDbGridTestForm.mygridDrawColumnCell(Sender: TObject;
  const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState);
begin
  if  gdSelected in State then begin
      //      mygrid.DrawCellHighlight(Rect, State, Col, Row);
  mygrid.Canvas.Brush.Color := clHighlight;
  mygrid.Canvas.Font.Color := clHighlightText;
  mygrid.Canvas.FillRect(Rect);
  end;


  mygrid.DefaultDrawColumnCell(Rect, DataCol, Column, State);

end;

And what is driving me crazy is that focus indication (the highlight color and focus rectangle) are not drawn by the DefaultDrawColumnCell code, and I'm sure I should be invoking DrawCellHighlight instead of doing the FillRect hack I'm doing above.

If I turn on DefaultDrawing, I get one set of glitches (odd font painting issues) and if I turn it off, I get another set of glitches (no highlight even when gdSelected).

The code in DBGrids.pas DefaultDrawColumnCell does nothing other than paint the text. So clearly, you're supposed to do more, if you take over all the drawing code yourself. However, the highlight drawing code built into Grids.pas, upon which DBGrids.pas depends, is not designed to be invoked from this context. I can't figure out if I should be invoking DrawCellHighlight directly (shown commented out above), and figuring out Col and Row values, or if I should be writing my own complex version of TCustomGrid.DrawCellHighlight that handles all the various cases manually.

Surely this is so simple, and obvious, and I'm just overlooking it. NOte that I must leave DefaultDrawing off, and so I must completely paint from within my owner draw event, and that I must be able to run when theme services are not available, and I must use theme services when they are available. So I need to invoke TCustomGrid.DrawCellHighlight directly (and I don't know how to), or I need to reimplement it entirely.

Jugal answered 27/2, 2012 at 16:47 Comment(0)
P
4

You're better off invoking DrawCellHighlight due to the theme support that you'd need to implement yourself. Even though the row number is not provided to OnDrawColumnCell it doesn't look like it's even used by the DefaultDrawColumnCell code so you don't have to try to calculate it internally:

type
  tHackGrid = class(tDBGrid);

procedure TTDbGridTestForm.myGridDrawColumnCell(Sender: TObject; const Rect: TRect;
  DataCol: Integer; Column: TColumn; State: TGridDrawState);
begin
  if gdSelected in State then begin
    tHackGrid(mygrid).DrawCellHighlight(Rect, State, Column.Index, 0);
  end;
  mygrid.DefaultDrawColumnCell(Rect, DataCol, Column, State);
end;
Phloem answered 27/2, 2012 at 20:45 Comment(3)
That looks reasonable enough.Jugal
@Mike W, how can i change row background color?Encrust
tHackGrid(mygrid).Canvas.Brush.Color := clRed; // Not working !!Encrust
C
0
type
  tHackGrid = class(tDBGrid);

procedure MyForm.MyDbGridDrawColumnCell(Sender: TObject;
const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState);
var ImageIndex: integer;
begin
  if gdSelected in State
  then tHackGrid(Sender).DrawCellHighlight(Rect, State, Column.Index, 0)
  else tHackGrid(Sender).DrawCellBackground(Rect, Column.Color, State, Column.Index, 0);
  TDbGrid(Sender).DefaultDrawColumnCell(Rect, DataCol, Column, State);
end;
Contiguous answered 25/9, 2015 at 13:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.