Create a TStringGrid with one column of runtime created buttons in it (Views: 32)
Problem/Question/Abstract: I want the following: A StringGrid with 1 column of buttons in it. The number of rows in the grid is not known at design time, so the buttons are created at runtime. Answer: TSpeedButton will work and you won't have to worry about the TabStop. The problem with using the Rect that comes in as a param, it doesn't hit all the cells in the column. So what you end up with is buttons displaying in the wrong cells. If it doesn't matter, then you're ok. But if it does, then you'll need to update the entire column for all the visible cells. Here's what I came up with: { ... } var HelpButtons: array of TSpeedButton; procedure Form1.CreateTheButtons; var i: Integer; begin SetLength(HelpButtons, ParamGrid.RowCount - 1); for i := 0 to ParamGrid.RowCount - 2 do begin HelpButtons[i] := TSpeedButton.Create(Self); HelpButtons[i].Visible := False; HelpButtons[i].Parent := ParamGrid; HelpButtons[i].Caption := IntToStr(i) + ' ?'; HelpButtons[i].Width := 34; HelpButtons[i].Height := 18; HelpButtons[i].Tag := i; HelpButtons[i].OnClick := ParamGridButtonClick; end; {Force the buttons to show} ParamGrid.Refresh; end; procedure TForm1.ParamGridDrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState); procedure UpdateTheColumn; var i: Integer; R: TRect; begin for i := ParamGrid.TopRow to (ParamGrid.VisibleRowCount + ParamGrid.TopRow) do begin if i >= ParamGrid.RowCount then Break; R := ParamGrid.CellRect(2, i); HelpButtons[i - 1].Top := R.Top; HelpButtons[i - 1].Left := R.Left; if not HelpButtons[i - 1].Visible then HelpButtons[i - 1].Visible := True; end; end; begin if Length(HelpButtons) = 0 then Exit; if not FRefresh then Exit; if ((ACol = 2) and (ARow > 0)) then begin UpdateTheColumn; end; end; procedure TForm1.ParamGridButtonClick(Sender: TObject); begin ShowMessage('Click ' + Sender.ClassName + ' ' + IntToStr(TControl(Sender).Tag)); end; |