How to Programmatically Scroll a Panel

Marwan مروان picture Marwan مروان · Jul 19, 2013 · Viewed 63.2k times · Source

I have a System.Windows.Forms.Panel with some content.

I am trying to programmatically scroll the panel (vertically) either up or down.

I have tried setting the AutoScrollPosition property to a new Point on the panel but that doesn't seem to do it.

I have the AutoScroll property set to true.

I even tried to set the VerticalScroll.Value twice as suggested here, but that doesn't seem to work either.

This is what I am currently doing:

//I have tried passing both positive and negative values.
panel.AutoScrollPosition = new Point(5, 10);

The X and Y values on AutoScrollPosition remain 0 and 0.

Any help or direction on this would be greatly appreciated it.

Thanks in advance,

Marwan

Answer

King King picture King King · Jul 19, 2013

Here is a solution. I guess you can scroll your Panel by arbitrary position using Win32 however there is a simple trick to help you achieve your requirement here:

public void ScrollToBottom(Panel p){
  using (Control c = new Control() { Parent = p, Dock = DockStyle.Bottom })
     {
        p.ScrollControlIntoView(c);
        c.Parent = null;
     }
}
//use the code
ScrollToBottom(yourPanel);

Or use extension method for convenience:

public static class PanelExtension {
   public static void ScrollToBottom(this Panel p){
      using (Control c = new Control() { Parent = p, Dock = DockStyle.Bottom })
      {
         p.ScrollControlIntoView(c);
         c.Parent = null;
      }
   }
}
//Use the code
yourPanel.ScrollToBottom();

UPDATE

If you want to set the exact position, modifying the code above a little can help:

//This can help you control the scrollbar with scrolling up and down.
//The position is a little special.
//Position for scrolling up should be negative.
//Position for scrolling down should be positive
public static class PanelExtension {
    public static void ScrollDown(this Panel p, int pos)
    {
        //pos passed in should be positive
        using (Control c = new Control() { Parent = p, Height = 1, Top = p.ClientSize.Height + pos })
        {
            p.ScrollControlIntoView(c);                
        }
    }
    public static void ScrollUp(this Panel p, int pos)
    {
        //pos passed in should be negative
        using (Control c = new Control() { Parent = p, Height = 1, Top = pos})
        {
            p.ScrollControlIntoView(c);                
        }
    }
}
//use the code, suppose you have 2 buttons, up and down to control the scrollbar instead of clicking directly on the scrollbar arrows.
int i = 0;
private void buttonUp_Click(object sender, EventArgs e)
{
   if (i >= 0) i = -1;
   yourPanel.ScrollUp(i--);
}
private void buttonDown_Click(object sender, EventArgs e)
{
   if (i < 0) i = 0;
   yourPanel.ScrollDown(i++);
}

Another solution you may want to use is using Panel.VerticalScroll.Value. However I think you need more research to make it work as you expect. Because I can see once changing the Value, the scrollbar position and control position don't sync well. Notice that Panel.VerticalScroll.Value should be between Panel.VerticalScroll.Minimum and Panel.VerticalScroll.Maximum.