M Schenkel
M Schenkel

Reputation: 6364

Resizing buttons so they are all the same width

I have a "wide" TPanel with several buttons on it (essentially a tool bar). All the buttons have Align=Left. I have created a function which will resize the buttons to the same size and calculate the width of them so they fill the entire TPanel. I call this function in the OnResize event handler of the TPanel.

procedure ScaleButtonsOnPanel;
var i: Integer;
begin
  for i:=0 to mPanel.ControlCount-1 do begin
      mPanel.Controls[i].Width := round(mPanel.width/mPanel.ControlCount-1)
  end;
end;

The problem is if I minimize and then restore the form the layout of the buttons change from the design layout.

Can anyone offer a solution to having buttons on a panel which can be resized but maintain the design time order (in terms of left to right placement) ?

Upvotes: 1

Views: 2178

Answers (2)

Andreas Rejbrand
Andreas Rejbrand

Reputation: 109138

I do not really see your problem. But of course, you must set the position of the buttons, not only their size.

procedure TForm1.Panel1Resize(Sender: TObject);
var
  i: Integer;
  btnWidth: integer;
begin
  btnWidth := Panel1.Width div Panel1.ControlCount;
  for i := 0 to Panel1.ControlCount - 1 do
  begin
    Panel1.Controls[i].Left := i * btnWidth;
    Panel1.Controls[i].Width := btnWidth;
  end;
end;

This works very well.

See https://privat.rejbrand.se/panelresize.wmv.

OK, now I see. I think the alLeft is actually your problem. Controls with the same align tend to change their order. This is a well-known Delphi annoyance. Do it like I do above, instead. Just make sure that you go through the buttons in the right order. If you cannot rely on the ordering of Panel1.Controls, then you can do like this: Set the Tag property of each toolbar button to its position (0, 1, ...) in the toolbar then do

procedure TForm1.Panel1Resize(Sender: TObject);
var
  i: Integer;
  btnWidth: integer;
begin
  btnWidth := Panel1.Width div Panel1.ControlCount;
  for i := 0 to Panel1.ControlCount - 1 do
  begin
    Panel1.Controls[i].Left := Panel1.Controls[i].Tag * btnWidth;
    Panel1.Controls[i].Width := btnWidth;
  end;
end;

Upvotes: 4

Francesca
Francesca

Reputation: 21650

Have you tried to see if a TFlowPanel doesn't better suit your needs?

Upvotes: 2

Related Questions