在 TStringGrid 的单元格中的按钮上绘制和图像
Drawing and image on a button in a cell in a TStringGrid
我在 Lazarus 中有一个 TStringGrid,运行 在 Linux 中。我有一个编辑器类型为 cbsButton 的专栏。我希望按钮显示特定图像,而不是省略号。我有以下代码,它会导致错误:
procedure TForm1.streams_gridDrawCell(Sender: TObject; aCol, aRow: Integer; aRect: TRect; aState: TGridDrawState);
var
aCanvas: TCanvas;
aGrid: TStringGrid;
Editor: TWinControl;
image: TImage;
begin
if (aCol <> 1) or (aRow = 0) then begin
Exit;
end;
aGrid := (Sender as TStringGrid);
aCanvas := image.Canvas;
aCanvas.FillRect(aRect);
imagelist1.Draw(aCanvas, aRect.Left+2, aRect.Top+2, 8);
Editor := (aGrid.EditorByStyle(cbsButton) as TButtonCellEditor);
Editor.Brush.Style := TBrushStyle.bsImage;
(Editor.Brush.Image as TImage) := image; // causes the error below
end;
错误是:
mainform.pas(156,23) Error: Class or Object types "TFPCustomImage" and
"TImage" are not related
在这一点上,我确定我正在以完全错误的方式处理这件事。有人可以让我回到正确的道路上吗?
Editor.Brush.Image
是类型 TFPCustomImage
的 属性。这是一个 TPersistent
后代。 TImage
是 TCustomImage
的后代,因此 TGraphicControl
和 TControl
。所以这些完全不同 类 不兼容。
因此您不需要转换 (Editor.Brush.Image as TImage)
并将任何 TImage 实例分配给它。
我怀疑 OnDrawCell 事件是修改单元格编辑器的正确位置,因为在绘制单元格时可能此时不存在正确的单元格编辑器。
定义单元格编辑器的正确事件是网格的OnSelectEditor 事件。请阅读 wiki (http://wiki.lazarus.freepascal.org/Grids_Reference_Page)。
您使用的cbsButton编辑器继承自TButton。 TButton 没有字形 属性 - 您不能将位图分配给按钮。但是你是否可以轻松编写自己的单元格编辑器,只需按照 examples/gridexamples/gridcelleditor:
中的标准示例即可
- 在表单中添加一个 TBitBtn。删除它的标题,将请求的图像添加到字形 属性。将可见 属性 设置为 false。
- 在此按钮的 OnClick 事件中写入您希望如何编辑单元格。访问由网格的属性 Col 和 Row 指定的单元格。例如,我假设您只想打开一个 InputBox:
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
StringGrid1.Cells[StringGrid1.Col, StringGrid1.Row] :=
InputBox('Input some text', 'Text:', '');
end;
- 现在为网格的OnSelectEditor 事件编写事件处理程序。它必须将 BitBtn 分配给事件的 Editor 参数,并确保按钮位于所选单元格内的正确位置 - 仅此而已!
procedure TForm1.StringGrid1SelectEditor(Sender: TObject; aCol, aRow: Integer;
var Editor: TWinControl);
var
R: TRect;
begin
if (aCol=2) and (aRow > 0) then begin
R := StringGrid1.CellRect(aCol, ARow);
R.Left := R.Right - (R.Bottom - R.Top);
BitBtn1.BoundsRect := R;
Editor := BitBtn1;
end;
end;
我在 Lazarus 中有一个 TStringGrid,运行 在 Linux 中。我有一个编辑器类型为 cbsButton 的专栏。我希望按钮显示特定图像,而不是省略号。我有以下代码,它会导致错误:
procedure TForm1.streams_gridDrawCell(Sender: TObject; aCol, aRow: Integer; aRect: TRect; aState: TGridDrawState);
var
aCanvas: TCanvas;
aGrid: TStringGrid;
Editor: TWinControl;
image: TImage;
begin
if (aCol <> 1) or (aRow = 0) then begin
Exit;
end;
aGrid := (Sender as TStringGrid);
aCanvas := image.Canvas;
aCanvas.FillRect(aRect);
imagelist1.Draw(aCanvas, aRect.Left+2, aRect.Top+2, 8);
Editor := (aGrid.EditorByStyle(cbsButton) as TButtonCellEditor);
Editor.Brush.Style := TBrushStyle.bsImage;
(Editor.Brush.Image as TImage) := image; // causes the error below
end;
错误是:
mainform.pas(156,23) Error: Class or Object types "TFPCustomImage" and "TImage" are not related
在这一点上,我确定我正在以完全错误的方式处理这件事。有人可以让我回到正确的道路上吗?
Editor.Brush.Image
是类型 TFPCustomImage
的 属性。这是一个 TPersistent
后代。 TImage
是 TCustomImage
的后代,因此 TGraphicControl
和 TControl
。所以这些完全不同 类 不兼容。
因此您不需要转换 (Editor.Brush.Image as TImage)
并将任何 TImage 实例分配给它。
我怀疑 OnDrawCell 事件是修改单元格编辑器的正确位置,因为在绘制单元格时可能此时不存在正确的单元格编辑器。
定义单元格编辑器的正确事件是网格的OnSelectEditor 事件。请阅读 wiki (http://wiki.lazarus.freepascal.org/Grids_Reference_Page)。
您使用的cbsButton编辑器继承自TButton。 TButton 没有字形 属性 - 您不能将位图分配给按钮。但是你是否可以轻松编写自己的单元格编辑器,只需按照 examples/gridexamples/gridcelleditor:
中的标准示例即可- 在表单中添加一个 TBitBtn。删除它的标题,将请求的图像添加到字形 属性。将可见 属性 设置为 false。
- 在此按钮的 OnClick 事件中写入您希望如何编辑单元格。访问由网格的属性 Col 和 Row 指定的单元格。例如,我假设您只想打开一个 InputBox:
procedure TForm1.BitBtn1Click(Sender: TObject); begin StringGrid1.Cells[StringGrid1.Col, StringGrid1.Row] := InputBox('Input some text', 'Text:', ''); end;
- 现在为网格的OnSelectEditor 事件编写事件处理程序。它必须将 BitBtn 分配给事件的 Editor 参数,并确保按钮位于所选单元格内的正确位置 - 仅此而已!
procedure TForm1.StringGrid1SelectEditor(Sender: TObject; aCol, aRow: Integer; var Editor: TWinControl); var R: TRect; begin if (aCol=2) and (aRow > 0) then begin R := StringGrid1.CellRect(aCol, ARow); R.Left := R.Right - (R.Bottom - R.Top); BitBtn1.BoundsRect := R; Editor := BitBtn1; end; end;