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

泄露秘密 提交于 2019-12-07 03:13:27

问题


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.


回答1:


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;



回答2:


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;


来源:https://stackoverflow.com/questions/9468791/how-do-i-do-a-proper-owner-draw-of-full-row-selected-tdbgrid-when-tdbgrid-defaul

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!