Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.4k views
in Technique[技术] by (71.8m points)

delphi - How to dynamically create controls aligned to the top but after other aligned controls?

In this particular case I'm using PowerPDF library to dynamically build a PDF document, but the same applies for the general concept of dynamically aligning controls sequentially inside of a parent control. In this library, TPRPage is the base control to contain all element controls, in this case, sequential instances of TPRLayoutPanel.

What I do when dynamically adding controls:

  1. Create a control (TPRLayoutPanel)
  2. Set the control's parent (TPRPage)
  3. Align the control to top (PRLayoutPanel.Align:= alTop;)

The problem is it gets forced to the very beginning (top) instead of the very end (bottom) of the page.

I've tried setting its order PRLayoutPanel.SendToBack; or PRLayoutPanel.BringToFront but with no luck.

How can I dynamically create and align multiple controls within a parent control sequentially? My only current work-around is to add the controls in reverse order (from end to beginning) which is ridiculously unnecessary.

Here's my universal function which creates every new instance of an aligned control in this parent:

function TfrmReport.InsertPanel: TPRLayoutPanel;
begin
  Result:= TPRLayoutPanel.Create(PRPage);
  Result.Parent:= PRPage;
  Result.Align:= alTop;
  Result.Height:= 40; //Default, may change later
end;
Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Once again, DisableAlign and EnableAlign to the rescue:

procedure TForm1.FormCreate(Sender: TObject);
var
  I: Integer;
  P: TPanel;
begin
  DisableAlign;
  try
    for I := 0 to 4 do
    begin
      P := TPanel.Create(Self);
      P.Caption := IntToStr(I);
      P.Align := alTop;
      P.Parent := Self;
    end;
  finally
    EnableAlign;
  end;
end;

Explanation:

When alignment is enabled, every single addition of a control to a container (the form itself in this specific case) will re-evaluate all alignment (and anchor) settings of all other controls within that container. In case that control has no specific Top property set, then Top will be 0. When there is already another control aligned to the top, then there are two controls with Top = 0, and the one which is about to inserted wins. I (currently) have no in-depth explanation for that, but it just is, and the position order indeed gets reversed from the creation order.

Now, when alignment of the container is disabled, then consecutive added controls are simply just inserted with all their positioning properties unaltered. When alignment is enabled again, then all those controls are re-evaluated in the same manner, with the difference that this takes place in one single loop in the order of the index in the Controls array; i.e. the order in which they were created.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...