C# WinForms:使面板滚动条不可见

8

我有一个 panel1,其 AutoScroll = true。我需要使用 btnUpbtnDown 来使 panel1 滚动。到目前为止,我已经完成了所要求的任务。

private void btnUpClicked(Object sender, EventArgs e)
{
    if (panel1.VerticalScroll.Value - 55 > 0)
        panel1.VerticalScroll.Value -= 55;
    else  panel1.VerticalScroll.Value = 0;
}

private void btnDownClicked(Object sender, EventArgs e)
{
    panel1.VerticalScroll.Value += 55;
}

但现在我需要隐藏滚动条或将其变为不可见状态。我尝试了:
panel1.VerticalScroll.Visible = false;

但是它不起作用。大家有什么想法吗?

这就是 AutoScroll=true 的作用...自动给你添加滚动条。除非你完全接管行为,否则无法同时实现两者。 - DonBoitnott
是的,我就怕这样。我能做什么? - GugaMelkadze
如果你非常想要,你可以创建一个继承自“Panel”的新控件,然后实现自己的滚动。当然,这并不容易,但是可行的。有很多关于使用计时器等自定义滚动条的示例。 - DonBoitnott
@user3683349 我已经给你整个解决方案了,只需复制粘贴即可。看一下吧 ;) - msmolcic
3个回答

10

好的,我已经为您完成了这个工作示例。您需要做的就是根据面板内所有物品的总大小更改最大值。


表单代码:

public partial class Form1 : Form
{
    private int location = 0;

    public Form1()
    {
        InitializeComponent();

        // Set position on top of your panel
        pnlPanel.AutoScrollPosition = new Point(0, 0);

        // Set maximum position of your panel beyond the point your panel items reach.
        // You'll have to change this size depending on the total size of items for your case.
        pnlPanel.VerticalScroll.Maximum = 280;
    }

    private void btnUp_Click(object sender, EventArgs e)
    {
        if (location - 20 > 0)
        {
            location -= 20;
            pnlPanel.VerticalScroll.Value = location;
        }
        else
        {
            // If scroll position is below 0 set the position to 0 (MIN)
            location = 0;
            pnlPanel.AutoScrollPosition = new Point(0, location);
        }
    }

    private void btnDown_Click(object sender, EventArgs e)
    {
        if (location + 20 < pnlPanel.VerticalScroll.Maximum)
        {
            location += 20;
            pnlPanel.VerticalScroll.Value = location;
        }
        else
        {
            // If scroll position is above 280 set the position to 280 (MAX)
            location = pnlPanel.VerticalScroll.Maximum;
            pnlPanel.AutoScrollPosition = new Point(0, location);
        }
    }
}

图片示例:

Pic1 Pic2

您需要将面板上的AutoScroll选项设置为False。希望您明白我所做的,并且设置好您想要的面板。如果您有任何问题,请随时问我。


如何将 pnlPanel.VerticalScroll.Maximum 设置为自动?我用按钮填充面板,希望其最大滚动大小为自动。 - user8486381
我知道我来晚了,假设你到目前为止还没有找到方法... 要做到这一点,您必须获取面板中包含的控件数量,并将其乘以控件的高度和上下边距,然后将最大滚动值设置为该结束结果,并在每次添加控件时更改它! - Anass Hadeg

5
Panel控件非常严肃地承担了您给予它的任务,通过将AutoScroll设置为true。这始终包括在必要时显示滚动条小部件。因此,您尝试的内容无法正常工作,隐藏垂直滚动条会强制Panel重新计算布局,因为这样做改变了客户端区域。当然,它会发现需要滚动条并立即再次使其可见。
执行此操作的代码(Panel从ScrollableControl继承)是内部的,无法被覆盖。这是有意为之的。
因此,使用AutoScroll无济于事。作为替代方案,请记住您真正想要实现的目标。您只需上下移动控件。这很容易做到,只需更改它们的Location属性即可。为此,最简单的方法是将控件放在另一个足够大以容纳它们的面板上。将其AutoSize属性设置为True。并通过简单地更改该面板的Location属性来实现按钮的Click事件处理程序:
private const int ScrollIncrement = 10;

private void ScrollUpButton_Click(object sender, EventArgs e) {
    int limit = 0;
    panel2.Location = new Point(0, 
        Math.Min(limit, panel2.Location.Y + ScrollIncrement));
}

private void ScrollDownButton_Click(object sender, EventArgs e) {
    int limit = panel1.ClientSize.Height - panel2.Height;
    panel2.Location = new Point(0, 
        Math.Max(limit, panel2.Location.Y - ScrollIncrement));
}

其中panel1是外层面板,panel2是包含控件的内层面板。当使用设计师将控件放在它上面时,请小心,它有一个倾向于给它们错误的父级。一定要使用视图+其他窗口+文档布局助手窗口,这样你就可以看到这个问题。在填充后,将其AutoSizeMode属性设置为GrowAndShrink,以便它自动调整到最小大小。


0

试试这个:

panel.AutoScroll = true;
panel.VerticalScroll.Enabled = false;
panel.VerticalScroll.Visible = false;

编辑:

实际上,当AutoScroll = true时,它会自动处理hscroll和vscroll,您将无法更改它。我在MSDN上的Panel.AutoScroll属性中发现了这一点。

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

您可以尝试以下方法来解决这个问题,我从这个链接复制了它。

行为观察 1:

如果将AutoScroll设置为true,则无法修改VerticalScroll或HorizontalScroll中的任何内容。 AutoScroll指自动滚动;控件决定何时显示滚动条、最小/最大值等等,并且您无法更改任何内容。因此,如果要自定义滚动(例如隐藏滚动条),必须将AutoScroll设置为false。

通过使用Lutz Roeder的 .NET Reflecter查看ScrollableControl的源代码,您可以发现,如果AutoScroll设置为true,则会忽略您在VerticalScroll或HorizontalScroll属性内更改属性值(如MinValue、MaxValue、Visible等)的尝试。

行为观察 2:

当AutoScroll设置为false时,您可以更改VerticalScroll.Minimum、VerticalScroll.Maximum和VerticalScroll.Visible值。 但是,您无法更改VerticalScroll.Value!!! 真是鬼畜!如果将其设置为非零值,则会将其重置为零。 相反,您必须设置AutoScrollPosition = new Point(0,desired_vertical_scroll_value)。 最后,惊喜的是,当您分配正值时,它们会翻转为负值,因此如果您检查AutoScrollPosition.X,则为负数!将其分配为正数,它会变成负数。 所以,如果您想要自定义滚动,请将AutoScroll设置为false。然后设置VerticalScroll和HorizontalScroll属性(除了Value)。然后要更改滚动值,您需要设置AutoScrollPosition,即使您没有使用自动滚动!最后,当您设置AutoScrollPosition时,它将采用相反(即负)值,因此如果您稍后想要检索当前的AutoScrollPosition,例如如果您想通过拖动鼠标来平移滚动值,则需要记住在重新分配带有一些偏移量的AutoScrollPosition之前否定返回的值。哇。真是鬼畜。

另外一件事,如果你想用鼠标平移,请使用Cursor.Position的值而不是鼠标事件参数返回的任何鼠标位置。滚动控件也会导致事件参数值偏移,这将导致它开始触发带有不需要的值的鼠标移动事件。只需使用Cursor.Position,因为它将使用鼠标屏幕坐标作为固定参考框架,这正是您在尝试平移/偏移滚动值时所需要的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接