C# WinForms: Make panel scrollbar invisible

2019-06-17 15:41发布

问题:

I have a panel1 with AutoScroll = true.I have to make panel1 scroll with btnUp and btnDown. So far I've made what I was asked for

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

But now I need to hide Scrollbar or make it invisible. I tried

panel1.VerticalScroll.Visible = false;

but it doesn't work. Any ideas guys?

回答1:

Ok, I've done the working example of this for you. All you have to do is to change the max value depending on the total size of all the items inside your panel.


Form code:

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

Picture example:

You have to set AutoScroll option to False on your panel. I hope you understand what I've done and will get your panel running the way you want. Feel free to ask if you have any questions.



回答2:

The Panel control takes on the duty you gave it by setting AutoScroll to true pretty serious. This always includes displaying the scrollbar gadget if it is necessary. So what you tried cannot work, hiding the vertical scrollbar forces Panel to recalculate layout since doing so altered the client area. It will of course discover that the scrollbar is required and promptly make it visible again.

The code that does this, Panel inherits it from ScrollableControl, is internal and cannot be overridden. This was intentional.

So using AutoScroll isn't going to get you anywhere. As an alternative, do keep in mind what you really want to accomplish. You simply want to move controls up and down. Easy to do, just change their Location property. That in turn is easiest to do if you put the controls on another panel, big enough to contain them. Set its AutoSize property to True. And implement you buttons' Click event handlers by simply changing that panel's Location property:

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

Where panel1 is the outer panel and panel2 is the inner one that contains the controls. Be careful when you use the designer to put controls on it, it has a knack for giving them the wrong Parent. Be sure to use the View + Other Windows + Document Layout helper window so you can see this going wrong. After you filled it, set its AutoSizeMode property to GrowAndShrink so it snaps to its minimum size.



回答3:

Try this:

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

Edit:

Actually when AutoScroll = true; It will take care of hscroll and vscroll automatically and you wont be able to change it. I found this on Panel.AutoScroll Property on MSDN

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

You may try this to workaround this problem, I have copied it from this Link.

Behavior Observations 1:

If AutoScroll is set to true, you can't modify anything in VerticalScroll or HorizontalScroll. AutoScroll means AutoScroll; the control decides when scrollbars are visible, what the min/max is, etc. and you can't change a thing. So if you want to customize the scrolling (e.g. hide scrollbars), you must set AutoScroll to false.

Looking at the source code for the ScrollableControl with Lutz Roeder's .NET Reflecter, you can see that if AutoScroll is set to true, it ignores your attempts to change property values within the VerticalScroll or HorizontalScroll properties such as MinValue, MaxValue, Visible etc.

Behavior Observations 2:

With AutoScroll set to false, you can change VerticalScroll.Minimum, VerticalScroll.Maximum, VerticalScroll.Visible values. However, you cannot change VerticalScroll.Value!!! Wtf! If you set it to a non-zero value, it resets itself to zero. Instead, you must set AutoScrollPosition = new Point( 0, desired_vertical_scroll_value ); And finally, SURPRISE, when you assign positive values, it flips them to negative values, so if you check AutoScrollPosition.X, it will be negative! Assign it positive, it comes back negative. So yeah, if you want custom scrolling, set AutoScroll to false. Then set the VerticalScroll and HorizontalScroll properties (except Value). Then to change the scroll value, you need to set AutoScrollPosition, even though you aren't using auto scrolling! Finally, when you set the AutoScrollPosition, it will take on the opposite (i.e. negative) value that you assign to it, so if you want to retrieve the current AutoScrollPosition later, for example if you want to offset the scroll value by dragging the mouse to pan, then you need to remember to negate the value returned by AutoScrollPosition before reassigning it to AutoScrollPosition with some offset. WOW. Wtf.

One other thing, if you are trying to pan with the mouse, use the values of Cursor.Position rather than any mouse locations returned by the mouse events parameters. Scrolling the control will cause the event parameter values to be offset as well, which will cause it to start firing mouse move events complete with undesired values. Just use Cursor.Position, because it will use mouse screen coordinates as a fixed frame of reference, which is what you want when you're trying to pan/offset the scroll value.