ScrollableControl中的HScroll/VScroll有什么用?

What's the use of HScroll/VScroll in ScrollableControl?

ScrollableControl class 有 2 个受保护的布尔属性:HScroll 和 VScroll。

正如 document 所说:

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

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

所以我这样使用它们,但是没有显示滚动条:

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

如果我使用以下代码,它会起作用:

this.HorizontalScroll.Visible = true;

当我把它们放在一起时,滚动条仍然不可见,并且 HScroll 和 HorizontalScroll.Visible 的值保持 False。

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

那么HScroll和VScroll的真正用途是什么?


更新

我的代码和测试

HScroll会显示水平滚动条是AutoScroll属性未定义。

在你所有没有出现滚动条的例子中,这是因为你将 AutoScroll 设置为 false,隐藏了任何滚动条的显示。

HScroll 属性 不直接影响滚动可见性,但它防止滚动被隐藏 HorizontalScroll.Visible

如果 HorizontalScroll.Visible 设置为 true,那么 HScroll 也会得到一个值 true(参见 table 中的第二行)

如果 AutoScroll 设置为 true HorizontalScroll.Visible 始终保持 true 并且 HScroll 没有任何影响(见最后两行)

使用包含 3 个按钮和下一个处理程序代码的 Control 创建一个应用程序,并使用它看看到底发生了什么:

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();
}

用法(自动滚动 = false

要手动显示滚动设置 HorizontalScroll.Visibletrue

要手动隐藏滚动条,请将 HScroll 设置为 false,然后将 HorizontalScroll.Visible 设置为 false

用法(自动滚动 = true

HorizontalScroll.Visible 始终是 true 且无法更改

HScroll 没有任何影响

So what is the real use of HScroll and VScroll ?

当您有显示滚动条的意图时,您将它们设置为 true。但这还不够,您还必须说明他们应该显示什么。滚动条需要知道拇指大小、最小和最大位置以及当前位置。

你正在与内部进行斗争ApplyScrollbarChanges() method。它做的一件事是隐藏滚动条,即使 HScroll 或 VScroll 设置为 true,如果它没有足够的信息来配置滚动条。该方法的代码太大,无法放在这里,简而言之,它从以下位置派生此信息:

  1. AutoScrollMinWidth 的值属性。
  2. 如果控件具有非默认布局,则它允许该控件的布局引擎确定滚动边界。这仅适用于 FlowLayoutPanel 和 TableLayoutPanel 控件。
  3. 如果控件具有默认布局,则它会迭代子控件以查看它们的边界。

项目 2 是一个有吸引力的自定义角度,但它们将 LayoutEngine class 设为内部,因此您无法派生自己的。第 3 项与 AutoLayout = true 已经做的并没有根本的不同。但是它确实有效,只需在构造函数中添加一个控件,覆盖 OnClientSizeChanged() 以调用 AdjustFormScrollbars(true),您现在将看到滚动条。

留下第 1 项来控制滚动条。 属性 setter 看起来 like this。是的,它偷偷地将 AutoScroll 属性 设置回 true :)

只需设置 AutoScrollMinSize 属性 即可控制滚动条。