Search code examples
delphidelphi-7vcltstringgrid

TStringGrid with SpeedButtons


I want to have a button with icon at the end of each row.

Like here:

enter image description here

I tried this

procedure TMyFrame.sgrd1DrawCell(Sender: TObject; ACol,
  ARow: Integer; Rect: TRect; State: TGridDrawState);
var
  canvas: TCanvas;
  sgrd: TStringGrid;
  point: TPoint;
  btn: TSpeedButton;
begin
  sgrd := TStringGrid(Sender);
  canvas := sgrd.Canvas;

  canvas.FillRect(Rect);

  if (ACol = 1) then 
  begin
    point := Self.ScreenToClient(ClientToScreen(Rect.TopLeft));

    btn := TSpeedButton.Create(sgrd);

    btn.Parent := sgrd;

    btn.OnClick := SpeedButton1Click;
    btn.Tag := ARow;

    btn.enabled:=true;
    btn.visible:= true;

    btn.Top := point.Y;
    btn.Left := point.X;
    btn.Width := 20;
    btn.Height := 24;
  end;
end;

but the button doesn't look like "alive" although click event works. No click, hover animation, focus, etc.


Solution

  • The problem is that you are continuously creating a new speedbutton every time the cell needs refreshing. You must create the buttons in the Create event.

    procedure TForm1.FormCreate(Sender: TObject);
    var
      canvas: TCanvas;
      point: TPoint;
      btn: TSpeedButton;
      row : integer;
      rect: TRect;
    begin
      for row:=0 to stringGrid1.RowCount-1 do
       begin
        rect := stringGrid1.CellRect(1,row);
        point := ScreenToClient(ClientToScreen(Rect.TopLeft));
        btn := TSpeedButton.Create(StringGrid1);
        btn.Parent := StringGrid1;
        btn.OnClick := SpeedButton1Click;
        btn.Tag := row;
        btn.enabled:=true;
        btn.visible:= true;
        btn.Top := point.Y;
        btn.Left := point.X;
        btn.Width := 20;
        btn.Height := 24;
      end;