当 TDBGrid.DefaultDrawing 为 false 时,如何正确绘制全行选定 TDBGrid 的所有者?

Posted

技术标签:

【中文标题】当 TDBGrid.DefaultDrawing 为 false 时,如何正确绘制全行选定 TDBGrid 的所有者?【英文标题】:How do I do a proper owner-draw of Full Row Selected TDBGrid when TDBGrid.DefaultDrawing is false? 【发布时间】:2012-02-27 16:47:48 【问题描述】:

如果您有一个 TDBGrid、全行选择,并且始终显示选择,即使没有聚焦,并且您希望完全拥有它,您可以选择一个已弃用的事件 OnDrawDataCell 和一个新事件 @ 987654322@,我选择了后者,试试这个:

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,因此我必须完全从我的所有者绘制事件中进行绘制,并且我必须能够在主题服务不可用时运行,并且我必须在主题服务可用时使用它们。所以我需要直接调用 TCustomGrid.DrawCellHighlight (我不知道怎么做),或者我需要完全重新实现它。

【问题讨论】:

【参考方案1】:

您最好调用 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;

【讨论】:

这看起来很合理。 @Mike W,如何更改行背景颜色? tHackGrid(mygrid).Canvas.Brush.Color := clRed; // 不工作!!【参考方案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;

【讨论】:

以上是关于当 TDBGrid.DefaultDrawing 为 false 时,如何正确绘制全行选定 TDBGrid 的所有者?的主要内容,如果未能解决你的问题,请参考以下文章

python当密码正确输入,当密码错误时

更新:为啥当用户是管理员时关系有效,但当普通用户时不会?

当位于顶级栏目显示下级栏目,当位于二级栏目显示同级栏目,当位于三级目录,显示上级栏目

当应用程序在后台时扫描外围设备(例如,当屏幕锁定时)

psp一骑当千交叉冲击金手指

当组长有感