从 DrawColumnCell 中的前一行获取值
Getting a Value from a previous Row in DrawColumnCell
我有一个由 MyDAC 填充的 dbGrid-SQL-Query 设置为 RowSelect。
一列包含位置字符串,每个位置可以有多行。
我想做的是给出一个视觉反馈,以便更好地区分不同的位置。所以第一个位置的行应该有白色背景,第二个是灰色的,第三个是白色的,依此类推...
我知道如何给每一行设置不同的背景,但我很难检测到哪一行的位置发生了变化。
因此,在 DrawColumnCell
过程中,我想查看前一行的位置值以检测更改。我怎样才能做到这一点?
您必须实现一些逻辑来存储先前字段的值,并确定是否需要新颜色。
这是一个简单的例子。要设置它,只需几个步骤 - 为了简单起见,我从一个新的空白 VCL 表单应用程序开始。
- 在窗体上拖放一个 TClientDataSet,并将其名称更改为 CDS。
- 添加一个 TDataSource,并将其 DataSet 设置为 CDS。
- 接下来,添加一个 TDBGrid 并将其 DataSource 设置为 DataSource1
- 将 DBGrid.DefaultDrawing 更改为 False。
向表单的 private
部分添加三个新变量:
private
SameCity, SameColor: Boolean;
LastCity: string;
在窗体的OnCreate
事件中添加以下代码来设置数据和初始化变量:
procedure TForm1.FormCreate(Sender: TObject);
var
i: Integer;
begin
// One field dataset, with the exact same cities and rows
// you've shown in your question
CDS.FieldDefs.Add('City', ftString, 10);
CDS.CreateDataSet;
for I := 1 to 3 do
CDS.AppendRecord(['London']);
for i := 1 to 2 do
CDS.AppendRecord(['Paris']);
CDS.AppendRecord(['Berlin']);
for i := 1 to 2 do
CDS.AppendRecord(['New York']);
CDS.Open;
// Initialize variables for first use
LastCity := '';
SameColor := False;
SameCity := False;
end;
为 OnDrawDataCell
事件向 DBGrid 添加事件处理程序,代码如下:
procedure TForm1.DBGrid1DrawDataCell(Sender: TObject; const Rect: TRect;
Field: TField; State: TGridDrawState);
const
RowColors: array[Boolean] of TColor = (clWindow, clLtGray);
begin
// See if we're on the same city as the last row, and save the
// value in the current row for use next row.
SameCity := (Field.AsString = LastCity);
LastCity := Field.AsString;
// If they weren't the same, toggle the color value
if not SameCity then
SameColor := not SameColor;
// Set the row color and tell the grid to draw the row
(Sender as TDBGrid).Canvas.Brush.Color := RowColors[SameColor];
(Sender as TDBGrid).DefaultDrawDataCell(Rect, Field, State);
end;
我使用 OnDrawDataCell 而不是 OnDrawColumnCell 因为它不会在 header 行上调用或修复列,因此 DBGrid 将负责完全绘制这些内容。
运行 应用程序产生这些结果。
我有一个由 MyDAC 填充的 dbGrid-SQL-Query 设置为 RowSelect。 一列包含位置字符串,每个位置可以有多行。
我想做的是给出一个视觉反馈,以便更好地区分不同的位置。所以第一个位置的行应该有白色背景,第二个是灰色的,第三个是白色的,依此类推...
我知道如何给每一行设置不同的背景,但我很难检测到哪一行的位置发生了变化。
因此,在 DrawColumnCell
过程中,我想查看前一行的位置值以检测更改。我怎样才能做到这一点?
您必须实现一些逻辑来存储先前字段的值,并确定是否需要新颜色。
这是一个简单的例子。要设置它,只需几个步骤 - 为了简单起见,我从一个新的空白 VCL 表单应用程序开始。
- 在窗体上拖放一个 TClientDataSet,并将其名称更改为 CDS。
- 添加一个 TDataSource,并将其 DataSet 设置为 CDS。
- 接下来,添加一个 TDBGrid 并将其 DataSource 设置为 DataSource1
- 将 DBGrid.DefaultDrawing 更改为 False。
向表单的
private
部分添加三个新变量:private SameCity, SameColor: Boolean; LastCity: string;
在窗体的
OnCreate
事件中添加以下代码来设置数据和初始化变量:procedure TForm1.FormCreate(Sender: TObject); var i: Integer; begin // One field dataset, with the exact same cities and rows // you've shown in your question CDS.FieldDefs.Add('City', ftString, 10); CDS.CreateDataSet; for I := 1 to 3 do CDS.AppendRecord(['London']); for i := 1 to 2 do CDS.AppendRecord(['Paris']); CDS.AppendRecord(['Berlin']); for i := 1 to 2 do CDS.AppendRecord(['New York']); CDS.Open; // Initialize variables for first use LastCity := ''; SameColor := False; SameCity := False; end;
为
OnDrawDataCell
事件向 DBGrid 添加事件处理程序,代码如下:procedure TForm1.DBGrid1DrawDataCell(Sender: TObject; const Rect: TRect; Field: TField; State: TGridDrawState); const RowColors: array[Boolean] of TColor = (clWindow, clLtGray); begin // See if we're on the same city as the last row, and save the // value in the current row for use next row. SameCity := (Field.AsString = LastCity); LastCity := Field.AsString; // If they weren't the same, toggle the color value if not SameCity then SameColor := not SameColor; // Set the row color and tell the grid to draw the row (Sender as TDBGrid).Canvas.Brush.Color := RowColors[SameColor]; (Sender as TDBGrid).DefaultDrawDataCell(Rect, Field, State); end;
我使用 OnDrawDataCell 而不是 OnDrawColumnCell 因为它不会在 header 行上调用或修复列,因此 DBGrid 将负责完全绘制这些内容。
运行 应用程序产生这些结果。