当TDBGrid.DefaultDrawing为false时,如何进行正确的完整行选择TDBGrid的所有者绘制?

6

当您拥有一个TDBGrid、全行选择和始终显示选择(即使未聚焦),并且希望完全自定义它时,您可以选择使用已弃用的事件OnDrawDataCell或新的事件DrawColumnCell。我选择了后者并尝试了以下代码:

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;

让我着迷的是,焦点指示(高亮颜色和焦点矩形)并未被 DefaultDrawColumnCell 代码绘制,我确信应该调用 DrawCellHighlight 而不是上面所做的 FillRect hack。
如果我打开 DefaultDrawing,我会得到一组故障(奇怪的字体绘制问题),如果我关闭它,我会得到另一组故障(即使是 gdSelected 也没有高亮)。
DBGrids.pas 中的代码 DefaultDrawColumnCell 除了绘制文本之外什么都不做。因此,如果你接管了所有的绘制代码,显然需要做更多的工作。然而,Grids.pas 中内置的高亮绘制代码,DBGrids.pas 依赖于它,不是为在这种情况下调用而设计的。我搞不清楚是否应该直接调用 DrawCellHighlight(如上所注释的),并找出 Col 和 Row 值,还是自己编写 TCustomGrid.DrawCellHighlight 的复杂版本来手动处理各种情况。
这肯定很简单,很明显,我只是忽略了它。请注意,我必须禁用 DefaultDrawing,因此必须完全从我的 owner draw 事件中绘制,并且必须能够在主题服务不可用时运行,在可用时使用主题服务。因此,我需要直接调用 TCustomGrid.DrawCellHighlight(我不知道如何做),或者完全重新实现它。
2个回答

4

由于需要自己实现主题支持,因此最好调用DrawCellHighlight。即使OnDrawColumnCell没有提供行号,但似乎DefaultDrawColumnCell代码也没有使用它,因此您无需尝试在内部计算行号:

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;

1
那看起来足够合理。 - Warren P
@Mike W,我该如何更改行的背景颜色? - Ganpat
tHackGrid(mygrid).Canvas.Brush.Color := clRed; // 不起作用!! - Ganpat

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;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接