delphi - TDBGrid:OnDrawColumnCell 数据重叠

标签 delphi delphi-10.2-tokyo tdbgrid

我正在使用Delphi 10.2SQL Server 2008

我必须修改TDBGrid中的一些值。当我使用 OnDrawColumnCell 修改值时,当我单击该列时,数据会重叠,并且在 Delphi 7 中同样工作正常。

enter image description here

示例代码:

SQL Server 2008中创建表并插入一些数据。

CREATE TABLE [dbo].[Persons](
    [P_ID] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY,
    [LastName] [varchar](15) NOT NULL,
)
insert into Persons (LastName) values ('LastName')

创建新的 VCL 表单应用程序 - Delphi

要在 DBGrid 上显示数据,我使用 TADOCOnnectionTADOQueryTDataSourceTDBGrid

TADOQuery.SQL设置为“从人员中选择姓氏”

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Grids, DBGrids, DB, ADODB, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    ADOConnection1: TADOConnection;
    ADOQuery1: TADOQuery;
    DataSource1: TDataSource;
    DBGrid1: TDBGrid;
    procedure FormShow(Sender: TObject);
    procedure DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
      DataCol: Integer; Column: TColumn; State: TGridDrawState);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormShow(Sender: TObject);
begin
  ADOQuery1.Active := False;
  ADOQuery1.Active := True;
end;

procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
  DataCol: Integer; Column: TColumn; State: TGridDrawState);
Var
  CellData : String;
begin
  CellData := Column.Field.DisplayText;

  if Column.Field.FieldName = 'LastName' then
  begin
    CellData := 'change';
    DBGrid1.Canvas.TextRect(Rect, Rect.Left, Rect.Top, CellData);
  end
  else
    DBGrid1.DefaultDrawColumnCell(Rect, DataCol, Column, state);
end;

end.

最佳答案

这是一个一般绘图问题,与 SQL Server 或 TDBGrid 特别无关。这同样适用于绘制到 VCL TCanvas 或类似的东西。

在绘制文本之前清除区域

您正在调用 Canvas.TextRect(..),但仅此而已。文本将被绘制,但仅此而已。您必须先清理该区域:想象一下在绘制黑色文本之前绘制白色背景。

TDBGrid 提供了一种便捷的方法 DrawCellBackground(..) 。由于此方法不是公开的,因此迫切需要利用辅助类来实现它。

实现示例

以下代码在选择单元格时使用 DrawCellHighlight(..) 清除单元格绘制区域,否则使用 DrawCellBackground(..)

type
    TDBGridHelper = class helper for TDBGrid
        public const textPaddingPx = 2; // Siehe TDBGrid::DefaultDrawColumnCell
        public procedure writeText(
            const   inRect:         TRect;
            const   text:           String;
            const   State:          TGridDrawState;
            const   columnIndex:    Integer
        );
    end;

procedure TDBGridHelper.writeText(
    const   inRect:         TRect;
    const   text:           String;
    const   State:          TGridDrawState;
    const   columnIndex:    Integer
);
const
    cellGridPx = 1;
var
    backgroungRect: TRect;
begin
    backgroungRect := inRect;
    backgroungRect.Inflate(-cellGridPx, -cellGridPx);

    if (Vcl.Grids.gdSelected in State) then
        DrawCellHighlight(inRect, State, columnIndex, 0)
    else
        DrawCellBackground(backgroungRect, self.Color, State, Columnindex, 0);

    Canvas.TextRect(
        inRect,
        inRect.Left + textPaddingPx,
        inRect.Top + textPaddingPx,
        text
    );
end;

利用 TDBGrid.OnDrawColumnCell 事件是绝对正确的,您现在可以将其简化为类似的内容

procedure TYourFrame.dbGridDrawColumnCell(
    Sender: TObject;
    const Rect: TRect;
    DataCol: Integer;
    Column: TColumn;
    State: TGridDrawState
);
var
    columnText:     String;
begin
    columnText := '---';
    if Assigned(Column.Field) then begin
        if (Column.FieldName = 'yourField') then
            columnText := getDeviationColumnText(Column.Field.AsSingle)
        else
            // This is the default text
            columnText := Column.Field.DisplayText; 
    end;
    (Sender as TDBGrid).writeText(Rect, columnText, State, Column.Index);
end;

关于delphi - TDBGrid:OnDrawColumnCell 数据重叠,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49811572/

相关文章:

delphi - 在 Delphi 中合并两个或多个 pdf 文件的最简单方法是什么?

Delphi TList<T> 泛型

linux - Linux中简单的Delphi程序中的段错误-Windows很好

delphi - 如何获取编译器版本符号

mysql - 如何通过 dbgrid 更改 mysql 数据库的值?

Delphi dbgrid 连续滚动

database - 检查数据库连接是否仍然存在

sql-server - TFDQuery.Prepare 无法确定 MS SQL SERVER 上 INSERT 查询的参数类型

delphi - Delphi 中的只读 TDBGrid/TwwDBGrid 单元格?

delphi - 从网页中获取值(value)