9

The ScrollableControl class has 2 protected boolean properties: HScroll and VScroll.

As the document says:

Gets or sets a value indicating whether the horizontal scroll bar is visible.

And

AutoScroll maintains the visibility of the scrollbars automatically. Therefore, setting the HScroll or VScroll properties to true have no effect when AutoScroll is enabled.

So I use them like this, but the scrollbar isn't showed:

class MyScrollableControl : ScrollableControl {
    public MyScrollableControl() {
        this.AutoScroll = false;
        this.HScroll = true;
    }
}

If I use the following code, it works:

this.HorizontalScroll.Visible = true;

When I put them torgether, the scrollbar is still invisible, and the values of HScroll and HorizontalScroll.Visible keep False.

this.AutoScroll = false;
this.HScroll = true;
this.HorizontalScroll.Visible = true;

So what is the real use of HScroll and VScroll ?


Update

My code and test

enter image description here

shingo
  • 18,436
  • 5
  • 23
  • 42
  • Please, Set `AutoScroll` of the control to `false` in hosting window onLoad handler, and check the result. Not Set `AutoScroll` gives me unexpected results – ASpirin Sep 21 '17 at 05:58

3 Answers3

6

HScroll property does not affect scroll visibility directly, but it prevent Scroll to be hidden with HorizontalScroll.Visible value

enter image description here

In case when HorizontalScroll.Visible is set to true than HScroll will also get a value true (see 2nd line in the table)

In case when AutoScroll is set to true HorizontalScroll.Visible always stays true and HScroll doesnot have any influense (see last 2 lines)

Make an app with Control that contains 3 buttons with next handler code, and play with it to see what exactly happening there:

private void button1_Click(object sender, EventArgs e)
{
    AutoScroll = !AutoScroll;
    SetValues();
}

private void button3_Click(object sender, EventArgs e)
{
    HScroll = !HScroll;
    SetValues();
}

private void SetValues()
{
    button1.Text = $"Auto: {(AutoScroll ? "On" : "Off")}";
    button3.Text = $"HScroll: {(HScroll ? "On" : "Off")}";
    button2.Text = $"Visible: {(HorizontalScroll.Visible ? "On" : "Off")}";
}

private void button2_Click(object sender, EventArgs e)
{
    HorizontalScroll.Visible = !HorizontalScroll.Visible;
    SetValues();
}

Usage (AutoScroll = false)

To Manually show Scroll set HorizontalScroll.Visible to true

To Manually hide Scroll set HScroll to false and than HorizontalScroll.Visible to false

Usage (AutoScroll = true)

HorizontalScroll.Visible is always true and cannot be changed

HScroll doesnot affects anything

enter image description here

ASpirin
  • 3,601
  • 1
  • 23
  • 32
  • I test it under .Net 3.5 and .Net 4.6. but get the different result as yours. When set HScroll or VScroll to true, change the value of HorizontalScroll.Visible or VerticalScroll.Visible will make both HScroll and VScroll return to false, and hide the scrollbar. – shingo Sep 20 '17 at 11:33
  • Can you share results you've got – ASpirin Sep 20 '17 at 11:34
  • Checked on 3.5, results are added into the answer (on 4.6 results are the same) – ASpirin Sep 20 '17 at 12:39
  • I've add mine on the post. strange thing. maybe the behaviour of the property is based on OS? – shingo Sep 21 '17 at 03:10
  • I've checked on Win 10 and WinServer 2012, have the same result, difference that I'm starting from Auto enabled, will check – ASpirin Sep 21 '17 at 05:45
3

So what is the real use of HScroll and VScroll ?

You set them to true when you have the intention of showing the scrollbars. But that is not enough, you also have to state what they should display. A scrollbar needs to know the thumb size, minimum and maximum position and current position.

You are doing battle with the internal ApplyScrollbarChanges() method. One thing it does is hide the scrollbars, even if HScroll or VScroll is set to true, if it does not have sufficient info to configure the bars. The code of the method is too large to fit here, in a nutshell it derives this info from:

  1. The value of the AutoScrollMinWidth property.
  2. If the control has non-default layout then it allows the layout engine of that control to determine the scroll bounds. This is only the case for the FlowLayoutPanel and TableLayoutPanel controls.
  3. If the control has default layout then it iterates the child controls to look at their bounds.

Item 2 is an attractive customization angle, but they made the LayoutEngine class internal so you can't derive your own. Item 3 is not fundamentally different from what AutoLayout = true already does. It does work however, just add a control in the constructor, override OnClientSizeChanged() to call AdjustFormScrollbars(true) and you'll now see the scrollbar.

Which leaves item 1 to control the scrollbars. The property setter looks like this. Yup, it sneakily sets the AutoScroll property back to true :)

Simply set the AutoScrollMinSize property to control the scrollbars.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
2

HScroll will show the horizontal scroll bar is the AutoScroll property is not defined.

In all your examples where the scroll bars do not appear, it is because you have the AutoScroll set to false, hiding the display of any scroll bars.

Bejasc
  • 930
  • 1
  • 8
  • 20