Why is my TScrollBox not showing scrollbars?
Asked Answered
E

4

9

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.

Explain answered 27/1, 2012 at 16:29 Comment(0)
H
10

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.

Hedberg answered 27/1, 2012 at 17:1 Comment(4)
The TFlowPanel is now aligned clTop, and the VertScrollBar.Visible property is set to True. That didn't do it. In fact, the FlowPanel stopped re-positioning the controls within it, and neither horizontal or vertical scrollbars are appearing. Assuming that I had messed up some properties along the way, I deleted the flowpanel and scrollbox, and placed new instances. The ScrollBox is aligned alClient, AutoScroll is set to True, and VertScrollBar.Visible is True. The FlowPanel Align is set to alTop, AutoSize is True. Still no joy. No scrollbars appear, and flowpanel does not flow. Hmmm.Explain
Works perfectly over here. You should be aware that the AutoSize option hinders the flowpanel to reorder its controls when the scrollbox is resized (but that has nothing to do with the scrollbar). You can switch AutoWrap to false and back to true after the scrollbox is resized.Hedberg
I believe that your answer is the right one, and will accept it in the next day if someone else doesn't come up with the solution. I still have the problem, but my form is complex. It has 8 panels, 4 splitters, 4 DBGrids, and as many as 20 frames (in the flowpanel). The FlowPanel lies on a ScrollBox, which is aligned Client in another panel. In the same panel with the ScrollBox is another panel which is aligned top. My simple tests work, but none of these tests duplicate the complexity of this particular form.Explain
The answer is in your reply to my comment. I have added details about the solution to my post. Thank you!Explain
W
6

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.

Washbasin answered 10/11, 2013 at 17:16 Comment(0)
F
3

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.

Faceplate answered 22/8, 2016 at 17:50 Comment(0)
D
0

All efforts to get TScrollBox working failed to please but I was happy to find that dropping a TFlowPanel with AutoSize and AutoWrap set to true and its alignment set to alTop into a TPageScroller with Orientation = soVertical worked rather well. Scrolling ensued.

You may wish to embiggen the pagescroller's ButtonSize to allow it to stand out. 18 seems about right.

Drews answered 26/10, 2016 at 8:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.