Tengo un TStringGrid en Lazarus, que se ejecuta en Linux. Tengo una columna que tiene el tipo de editor cbsButton. Quiero que el botón muestre una imagen determinada, en lugar de una elipsis. Tengo el siguiente código, que causa un error:

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;

El error es:

mainform.pas (156,23) Error: los tipos de clase u objeto "TFPCustomImage" y "TImage" no están relacionados

En este punto, estoy seguro de que estoy haciendo esto de una manera completamente incorrecta. ¿Podría alguien volver a ponerme en el camino correcto?

0
lk75 18 ago. 2016 a las 18:47

2 respuestas

La mejor respuesta

Dudo que el evento OnDrawCell sea el lugar correcto para modificar un editor de celda porque probablemente el editor de celda correcto no existe en este momento cuando se pinta la celda.

El evento correcto para definir el editor de celdas es el evento OnSelectEditor de la cuadrícula. Lea la wiki (http://wiki.lazarus.freepascal.org/Grids_Reference_Page).

El editor cbsButton que usa hereda de TButton. Un TButton no tiene una propiedad Glyph; no puede asignar un mapa de bits al botón. Pero, ¿puede escribir su propio editor de celdas fácilmente? Simplemente siga el ejemplo estándar en examples / gridexamples / gridcelleditor :

  • Agregue un TBitBtn al formulario. Elimine su título, agregue la imagen solicitada a la propiedad Glyph. Establezca la propiedad Visible en falso.
  • En el evento OnClick de este botón, escriba cómo desea editar la celda. Acceda a la celda especificada por las propiedades Col y Fila de la cuadrícula. Como ejemplo, supongo aquí que solo desea abrir un InputBox:
    procedure TForm1.BitBtn1Click(Sender: TObject);
    begin
      StringGrid1.Cells[StringGrid1.Col, StringGrid1.Row] := 
        InputBox('Input some text', 'Text:', '');
    end;
  • Ahora escriba un controlador de eventos para el evento OnSelectEditor de la cuadrícula. Debe asignar BitBtn al parámetro Editor del evento y asegurarse de que el botón esté en la posición correcta dentro de la celda seleccionada, ¡eso es todo!
    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;
3
wp_1233996 19 ago. 2016 a las 23:24

Editor.Brush.Image es una propiedad de tipo TFPCustomImage. Este es un descendiente de TPersistent. Y TImage es descendiente de TCustomImage y, por tanto, TGraphicControl y TControl. Entonces, estas son clases completamente diferentes que no son compatibles.

Por lo tanto, no se espera que lance (Editor.Brush.Image as TImage) y le asigne ninguna instancia de TImage.

0
asd-tm 19 ago. 2016 a las 11:48