54

I am trying to make a Panel scrollable, but only vertically (so AutoScroll won't work because the child controls go past the left edge and must).

So how is this done?

Neuron
  • 5,141
  • 5
  • 38
  • 59
Seth Carnegie
  • 73,875
  • 22
  • 181
  • 249
  • So you want to have only the vertical scroll when it's necessary? So setting the `Scrollbars` property to `Vertical` won't work? – debracey May 22 '11 at 20:29
  • @debracey There isn't any property called `Scrollbars` on my `Panel` and it doesn't show up in Intellisense. I have seen other people talk about it so I think it exists but I'm just doing it wrong. I get this error for this line: `panel1.Scrollbars = ScrollBars.Vertical;` - `'System.Windows.Forms.Panel' does not contain a definition for 'Scrollbars' and no extension method 'Scrollbars' accepting a first argument of type 'System.Windows.Forms.Panel' could be found (are you missing a using directive or an assembly reference?)` – Seth Carnegie May 22 '11 at 20:33
  • @debracey I am using VS 2010 Pro. – Seth Carnegie May 22 '11 at 20:33

8 Answers8

51

Try this instead for 'only' scrolling vertical.
(auto scroll needs to be false before it will accept changes)

mypanel.AutoScroll = false;
mypanel.HorizontalScroll.Enabled = false;
mypanel.HorizontalScroll.Visible = false;
mypanel.HorizontalScroll.Maximum = 0;
mypanel.AutoScroll = true;
Neuron
  • 5,141
  • 5
  • 38
  • 59
kamgman
  • 744
  • 6
  • 9
  • 2
    Very good point for bringing up the fact that `AutoScroll` needs to be set to false, thankyou – mschr Jul 31 '16 at 09:57
33

Assuming you're using winforms, default panel components does not offer you a way to disable the horizontal scrolling components. A workaround of this is to disable the auto scrolling and add a scrollbar yourself:

ScrollBar vScrollBar1 = new VScrollBar();
vScrollBar1.Dock = DockStyle.Right;
vScrollBar1.Scroll += (sender, e) => { panel1.VerticalScroll.Value = vScrollBar1.Value; };
panel1.Controls.Add(vScrollBar1);

Detailed discussion here.

Neuron
  • 5,141
  • 5
  • 38
  • 59
Teoman Soygul
  • 25,584
  • 6
  • 69
  • 80
  • I really don't want to do this 'hack'. How can I do it manually with a `VScrollBar` component? – Seth Carnegie May 22 '11 at 20:35
  • @Teoman that example doesn't help, I can do that with the forms designer. What is the formula for determining what the max/min values of the scroll bar should be, how do I offset controls inside the panel when the scrollbar scrolls down, etc? – Seth Carnegie May 22 '11 at 20:42
  • All you need is to sync `VerticalScroll.Value` properties with the `Scroll` event. Updated the code. Note that to get the scroll effect, there should be some elements overflowing from the bottom edge of the panel (i.e. there should be some not-visible elements to scroll to). – Teoman Soygul May 22 '11 at 20:52
  • @Teoman How do I get the size of the grip in the scroll bar to change as there becomes more or less things "overflowing" from the bottom? And I just tried code very similar to yours and when I scroll down, everything jerks violently all around and doesn't scroll (even though there is stuff to scroll to in that instance). – Seth Carnegie May 22 '11 at 20:59
  • This may help: http://social.msdn.microsoft.com/Forums/en-IE/winforms/thread/6b9c2c72-e91a-40f0-a835-c12328490c0c – Teoman Soygul May 22 '11 at 21:12
  • @Teoman when it transitions from not overflowing to overflowing the horizontal scrollbar appears for a second and disappears, but I guess I'll have to settle for that. Thanks. – Seth Carnegie May 22 '11 at 21:31
  • When I on a control that has another control that is derived from ScrollabeControl, and I use the scrollbar, the vertical and horizontal scrollbar inside the ScrollabeControl are shown and hidden very quickly (flickering) and the contents doesn't seem to scroll as smooth as its own scrollbar. @Microsoft winforms department: How hard can it be to only have one scrollbar on control! – Mike de Klerk Feb 12 '14 at 13:31
  • This does not work at all...the scrollbar scrolls with the content, so when you scroll down you can't see the top up button on the scrollbar – Assimilater Jun 02 '17 at 23:55
6

AutoScroll is really the solution! You just have to set AutoScrollMargin to 0, 1000 or something like this, then use it to scroll down and add buttons and items there!

Xeevis
  • 4,325
  • 25
  • 26
OldMember
  • 59
  • 1
  • 7
5

Panel has an AutoScroll property. Just set that property to True and the panel will automatically add a scroll bar when needed.

Neuron
  • 5,141
  • 5
  • 38
  • 59
123iamking
  • 2,387
  • 4
  • 36
  • 56
3

Below is the code that implements custom vertical scrollbar. The important detail here is to know when scrollbar is needed by calculating how much space is consumed by the controls that you add to the panel.

panelUserInput.SuspendLayout();
panelUserInput.Controls.Clear();
panelUserInput.AutoScroll = false;
panelUserInput.VerticalScroll.Visible = false;

// here you'd be adding controls

int x = 20, y = 20, height = 0;
for (int inx = 0; inx < numControls; inx++ )
{
    // this example uses textbox control
    TextBox txt = new TextBox();
    txt.Location = new System.Drawing.Point(x, y);
    // add whatever details you need for this control
    // before adding it to the panel
    panelUserInput.Controls.Add(txt);
    height = y + txt.Height;
    y += 25;
}
if (height > panelUserInput.Height)
{
    VScrollBar bar = new VScrollBar();
    bar.Dock = DockStyle.Right;
    bar.Scroll += (sender, e) => { panelUserInput.VerticalScroll.Value =  bar.Value; };
    bar.Top = 0;
    bar.Left = panelUserInput.Width - bar.Width;
    bar.Height = panelUserInput.Height;
    bar.Visible = true;
    panelUserInput.Controls.Add(bar);
}
panelUserInput.ResumeLayout();

// then update the form
this.PerformLayout();
glinatser
  • 31
  • 2
1

3 steps:

1- just set AutoScroll property to true

2- in Form load()add the following:

   my Panel Vertical Scroll Maximum = 10000     

3- after my Panel controls Add(item) add the following: Invalidate();
Done!

0

Adding on to the answer by Kamgman which does work.

Let's say we were adding a label as the child control to the panel:

  • First add the panel. Set AutoScroll to True and AutoSize to False.
  • Add a label into the panel. Set AutoSize to true. You could give it a MinimumSize for the Width if you like so that it at least keeps its "shape" horizontally.
  • Then set the Anchor for the label control to Top only. Remove the Left anchor on it. This ensures the label only scrolls vertically but not horizontally.

If you go this route you don't have to add the lines to hide the horizontal scroll bar.

It might also be better if you're using System.ComponentModel.ComponentResourceManager.ApplyResources to load it from the .resx file instead of the .Designer.cs . Because in my case whenever I make edits to this particular form I lose the changes in the Designer.cs file. But that will come down to how your project is set up

SandstormNick
  • 1,821
  • 2
  • 13
  • 24
-2

Add to your panel's style code something like this:

<asp:Panel ID="myPanel" runat="Server" CssClass="myPanelCSS" style="overflow-y:auto; overflow-x:hidden"></asp:Panel>
Lukas
  • 2,885
  • 2
  • 29
  • 31