TDBGrid:OnDrawColumnCell 数据重叠
TDBGrid: OnDrawColumnCell Data is overlapping
我正在开发 Delphi 10.2 和 SQL Server 2008.
我必须修改 TDBGrid
中的一些值。当我使用 OnDrawColumnCell
修改值时,当我单击该列时,数据被重叠,并且在 Delphi 7.[=21= 中工作正常]
示例代码:
创建 table 并在 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
设置为"select LastName from Persons"
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 服务器或特定的 TDBGrid
无关。这同样适用于绘制到 VCL TCanvas
或类似的东西。
在绘制文本之前清除区域
您正在呼叫 Canvas.TextRect(..)
,但仅此而已。文本将被绘制,但仅此而已。您必须先清理该区域:想象在绘制黑色文本之前先绘制白色背景。
TDBGrid
提供了一个方便的方法DrawCellBackground(..)。由于此方法不是 public,因此需要利用助手 类.
来实现它
实现示例
以下代码使用 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;
如果浏览 30 个表格太单调乏味,您可以关闭 "Runtime themes" 以恢复 Windows 2000 年的花哨外观和随之而来的绘图算法。
- 选择“项目”>“选项”>“应用程序”。
- 清除“启用运行时主题”复选框。
来源:http://docwiki.embarcadero.com/RADStudio/en/Disabling_Themes_in_the_IDE_and_in_Your_Application
我正在开发 Delphi 10.2 和 SQL Server 2008.
我必须修改 TDBGrid
中的一些值。当我使用 OnDrawColumnCell
修改值时,当我单击该列时,数据被重叠,并且在 Delphi 7.[=21= 中工作正常]
示例代码:
创建 table 并在 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
设置为"select LastName from Persons"
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 服务器或特定的 TDBGrid
无关。这同样适用于绘制到 VCL TCanvas
或类似的东西。
在绘制文本之前清除区域
您正在呼叫 Canvas.TextRect(..)
,但仅此而已。文本将被绘制,但仅此而已。您必须先清理该区域:想象在绘制黑色文本之前先绘制白色背景。
TDBGrid
提供了一个方便的方法DrawCellBackground(..)。由于此方法不是 public,因此需要利用助手 类.
实现示例
以下代码使用 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;
如果浏览 30 个表格太单调乏味,您可以关闭 "Runtime themes" 以恢复 Windows 2000 年的花哨外观和随之而来的绘图算法。
- 选择“项目”>“选项”>“应用程序”。
- 清除“启用运行时主题”复选框。
来源:http://docwiki.embarcadero.com/RADStudio/en/Disabling_Themes_in_the_IDE_and_in_Your_Application