Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is my TScrollBox not showing scrollbars?

This seems like a very simple problem, but I cannot get a scrollbox to display scrollbars, and it is driving me crazy.

Here is the situation. I need to display a variable number of frames in a portion of a form. The area in which these frames are being displayed can be resized either through a TSplitter or by resizing the form.

I am dynamically generating the frames based on records in a database when the form is created. This frames are parented to a FlowPanel, which is responsible for frame placement. The FlowPanel is in a ScrollBox.

Due to the FlowPanel, when the user uses the TSplitter or resizes the form, the frames may re-align themselves. If any of the frames re-position out of the view of the form, I expect the ScrollBox to display scrollbars so that the user could scroll down to those inaccessible frames. This does not happen. Those frames that are in the area of the flowpanel outside the dimensions of the scrollbox are inaccessible.

I've built some tests with simple objects in a scrollbox, and the scrollbox correctly places scrollbars if any of its contained objects appear outside of the scrollbox's dimensions.

It does not matter if the flowpanel is aligned to clClient (the scrollbox) or anchored to the sides of the scrollbox, or none of these.

I realize that I can use a TPanel instead, and perform the placement and re-positioning of the frames in code from the panel's OnResize event handler, but this is what the FlowPanel is for.

What's going on here? I've fiddled around with many different scrollbox properties, and still can't get it to work. What's the issue, and is there a solution?


Ok. I am selecting Ewe's answer as correct, but the trick to making this work was in one of his comments, and I am still not completely satified with the results.

Here is the scoop. I did have my ScrollBox and FlowPanel configured the way that Ewe suggested, but played around with a number of other settings because that configuration did not work. I am pretty sure this was due to the complexity of the form's user interface, which has many panels in panels, many splitters, and the form itself is parented into a TabSheet of a PageControl (I omitted this fact since testing the form as a stand alone form produced the same results).

What made it work, albeit in a clunky fashion, is Ewe's suggestion to toggle the FlowPanel's AutoWrap off and on again. I added the following code to the OnResize event handler of the ScrollBox:

procedure TCurrentJobsForm.ScrollBox1Resize(Sender: TObject);
begin
  Flowpanel1.Autowrap := False;
  FlowPanel1.AutoWrap := True;
end;

There is a noticeable flicker when resizing, but I can live with that, since it produces the desired result. Once a user resizes the form, it will always be re-created using those dimensions, so resizing is something the user will do infrequently.

like image 566
Cary Jensen Avatar asked Jan 27 '12 16:01

Cary Jensen


3 Answers

The ScrollBox will only show scrollbars when the containg controls exceed the visible rectangle. As the only control inside your scrollbox is the flowpanel, it doesn't help to client align the flowpanel inside the scrollbox. This will always make the flowpanel equal the size of the scrollbox and thus no scrolling is necessary.

If you want f.i. vertical scrolling, make the flowpanel top aligned and auto sized. This should make the flowpanel height bigger when more frames are placed inside.

Just in case: check that the Visible property of the vertical scrollbar is set to true.

like image 174
Uwe Raabe Avatar answered Sep 21 '22 01:09

Uwe Raabe


I do not have Autosize true.
I have the flow panel on a Scrollbox. The flow planel align is set to leftRightTopBottom.

On the formresize event I do this:

procedure TForm2.FormResize(Sender: TObject);
var
 i,h:integer;
begin
 h:=0;
 for i:=0 to FlowPanel1.ControlCount - 1 do
  h:=Max(FlowPanel1.Controls[i].BoundsRect.Bottom,h);
 ScrollBox1.VertScrollBar.Range:=h;
end;

Works great.

like image 31
Mark Avatar answered Sep 22 '22 01:09

Mark


I had similar problem and I solved it with an adaptation of @Mark's code. Considering you have a FlowPanel1 and a ScrollBox1 on your Form1, you can try:

  • Set the ScrollBox1's Align property to alClient;
  • Put the FlowPanel1 on the ScrollBox1;
  • Set the FlowPanel1's FlowStyle property to fsLeftRightTopBottom.

Now, on the OnResize event of the Form1, just do:

procedure TForm1.FormShow(Sender: TObject);
var
  I: Integer;
  VButton: TButton;
begin
  for I := 1 to 10 do
  begin
    VButton := TButton.Create(FlowPanel1);
    VButton.Parent := FlowPanel1;
    VButton.Name := 'Button' + I.ToString;
    VButton.Height := 200;
    VButton.Width := 200;
  end;
end;

See the result in the picture below:

FlowPanel with scroll bars

HTH.

like image 44
silvioprog Avatar answered Sep 19 '22 01:09

silvioprog