我正在运行Lazarus v0.9.30(32位编译器)。
我有一个TForm和一个标准的TStringGrid。网格具有以下属性设置:RowCount = 5,ColumnCount = 5,FixedCols = 0,FixedRows = 0。
我谷歌了一下代码,展示了如何在用户单击TStringGrid单元格时更改单元格颜色并添加一些文本。所有工作都很好,我稍微扩展了一下,以便在GridClick事件上切换颜色/文本。
我有的问题更多是为了更好地理解代码中一些元素的目的。
有一个前景(FG)和背景(BG)TColor对象数组。它们是否用于存储在GridClick事件上设置的单元格颜色属性,以便如果需要任何原因触发DrawCell事件,则单元格可以重新绘制自己?你是否可以避免使用TColor数组,并根据需要在DrawCell事件中设置颜色/文本?
如果需要使用数组,我会假设它们的维度必须与Grid.ColCount和Grid.RowCount匹配(即通过Form.Create中的SetLength调用设置)
有办法检测您是否单击字符串网格的5 x 5个单元格之外的空白处,从而防止GridClick调用DrawCell事件。无论您单击哪里,您始终会获得行和列的有效值。
我有一个TForm和一个标准的TStringGrid。网格具有以下属性设置:RowCount = 5,ColumnCount = 5,FixedCols = 0,FixedRows = 0。
我谷歌了一下代码,展示了如何在用户单击TStringGrid单元格时更改单元格颜色并添加一些文本。所有工作都很好,我稍微扩展了一下,以便在GridClick事件上切换颜色/文本。
我有的问题更多是为了更好地理解代码中一些元素的目的。
有一个前景(FG)和背景(BG)TColor对象数组。它们是否用于存储在GridClick事件上设置的单元格颜色属性,以便如果需要任何原因触发DrawCell事件,则单元格可以重新绘制自己?你是否可以避免使用TColor数组,并根据需要在DrawCell事件中设置颜色/文本?
如果需要使用数组,我会假设它们的维度必须与Grid.ColCount和Grid.RowCount匹配(即通过Form.Create中的SetLength调用设置)
有办法检测您是否单击字符串网格的5 x 5个单元格之外的空白处,从而防止GridClick调用DrawCell事件。无论您单击哪里,您始终会获得行和列的有效值。
unit testunit;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs,
ExtCtrls, Menus, ComCtrls, Buttons, Grids, StdCtrls, Windows, Variants,
LCLType;
type
{ TForm1 }
TForm1 = class(TForm)
Grid: TStringGrid;
procedure FormCreate(Sender: TObject);
procedure GridClick(Sender: TObject);
procedure GridDrawCell(Sender: TObject; aCol, aRow: Integer;
aRect: TRect; aState: TGridDrawState);
end;
var
Form1: TForm1;
implementation
var
FG: array of array of TColor;
BG: array of array of TColor;
{$R *.lfm}
{ TForm1 }
procedure TForm1.FormCreate(Sender: TObject);
var
Col, Row: integer;
begin
// Set the sizes of the arrays
SetLength(FG, 5, 5);
SetLength(BG, 5, 5);
// Initialize with default colors
for Col := 0 to Grid.ColCount - 1 do begin
for Row := 0 to Grid.RowCount - 1 do begin
FG[Col, Row] := clBlack;
BG[Col, Row] := clWhite;
end;
end;
end;
procedure TForm1.GridDrawCell(Sender: TObject; aCol, aRow: Integer;
aRect: TRect; aState: TGridDrawState);
var
S: string;
begin
S := Grid.Cells[ACol, ARow];
// Fill rectangle with colour
Grid.Canvas.Brush.Color := BG[ACol, ARow];
Grid.Canvas.FillRect(aRect);
// Next, draw the text in the rectangle
Grid.Canvas.Font.Color := FG[ACol, ARow];
Grid.Canvas.TextOut(aRect.Left + 22, aRect.Top + 2, S);
end;
procedure TForm1.GridClick(Sender: TObject);
var
Col, Row: integer;
begin
Col := Grid.Col;
Row := Grid.Row;
// Set the cell color and text to be displayed
if (Grid.Cells[Col,Row] <> 'Yes') then
begin
BG[Col, Row] := rgb(131, 245, 44);
FG[Col, Row] := RGB(0, 0, 0);
Grid.Cells[Col, Row] := 'Yes'
end {if}
else
begin
BG[Col, Row] := rgb(255, 255, 255);
FG[Col, Row] := RGB(255, 255, 255);
Grid.Cells[Col, Row] := '';
end; {else}
end;
end.
OnPrepareCanvas
,它们只有OnDrawCell
,在那篇帖子中可以看到,你还需要渲染文本本身。如果您只想修改要呈现的单元格的画布属性,例如背景或字体颜色,则OnPrepareCanvas
是正确的阶段。关于StateYes
,您当然可以使用Yes
字符串进行比较,但是如果您将来想将其更改为Yeah
,则必须在多个位置进行更改 :-) - TLama