我正在使用Delphi 10.2和SQL Server 2008。
我必须修改TDBGrid
中的一些值。当我使用 OnDrawColumnCell
修改值时,当我单击该列时,数据会重叠,并且在 Delphi 7 中同样工作正常。
示例代码:
在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 上显示数据,我使用 TADOCOnnection
、TADOQuery
、TDataSource
和 TDBGrid
将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/