Auto Scroll Control on Panels

  • Thread starter Thread starter HaySeed
  • Start date Start date
H

HaySeed

I have a Panel which is being used as a paint surface. When the user presses
the up/down arrows or Page Up/ Down buttons I would like to scroll the panel
according to the proper increment.

Questions:
1) How do I get a handle to the AutoScroll Scrollbars when they are visible?
2) How do I increment the scrollbar (N) pixels down the panel?


I have tried the following Win32 call -

private const int WM_HSCROLL = 276;
private const int WM_VSCROLL = 277;
private const int SB_LINEUP = 0;
private const int SB_LINEDOWN = 1;
private const int SB_PAGEUP = 2;
private const int SB_PAGEDOWN = 3;
private const int SB_PAGETOP = 6;
private const int SB_PAGEBOTTOM = 7;
private const int SB_ENDSCROLL = 8;

SendMessage(panel.Handle, WM_VSCROLL, (IntPtr)SB_LINEDOWN,
IntPtr.Zero);

This does jump the scroll bar as needed but I could not find how to control
the distances the scrollbar would travel for a Line/Page/Top/Bottom etc.

Any thoughts would be appreciated.
 
HaySeed said:
I have a Panel which is being used as a paint surface. When the user presses
the up/down arrows or Page Up/ Down buttons I would like to scroll the panel
according to the proper increment.

Questions:
1) How do I get a handle to the AutoScroll Scrollbars when they are visible?
2) How do I increment the scrollbar (N) pixels down the panel?


I have tried the following Win32 call -

private const int WM_HSCROLL = 276;
private const int WM_VSCROLL = 277;
private const int SB_LINEUP = 0;
private const int SB_LINEDOWN = 1;
private const int SB_PAGEUP = 2;
private const int SB_PAGEDOWN = 3;
private const int SB_PAGETOP = 6;
private const int SB_PAGEBOTTOM = 7;
private const int SB_ENDSCROLL = 8;

SendMessage(panel.Handle, WM_VSCROLL, (IntPtr)SB_LINEDOWN,
IntPtr.Zero);

This does jump the scroll bar as needed but I could not find how to control
the distances the scrollbar would travel for a Line/Page/Top/Bottom etc.

Any thoughts would be appreciated.

Hi HaySeed,

You might find it easier if you just put the drawing-panel inside another
scrollable control and have the container control handle the scrolling. To
trap key events in your drawing-panel you need to create your own panel and
set Focus at some point, like at the MouseDown event. The code below
demonstrates how you can handle arrow key navigation in a panel. panel1 is
the fixed size control and will add scrollbars as needed. panel2 is the
drawing panel and can be larger than panel1. Note, the code is jotted down
quickly without regard for good design etc so you might want to tweak it
quite a bit and possibly look for better solutions.

public partial class Form1 : Form
{
public class MyPanel : Panel
{
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
}

protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);

Focus();
}
}

Panel panel1;
MyPanel panel2;

public Form1()
{
panel1 = new Panel();
panel1.Size = new Size(100, 100);
panel1.Location = new Point(10, 10);
panel1.AutoScroll = true;
panel1.BorderStyle = BorderStyle.FixedSingle;
Controls.Add(panel1);
panel2 = new MyPanel();
panel2.Size = new Size(300, 300);
panel2.Location = new Point(0, 0);
panel1.Controls.Add(panel2);

panel2.MouseDown += panel2_MouseDown;
panel2.Paint += panel2_Paint;
panel2.KeyDown += panel2_KeyDown;
}

void panel2_KeyDown(object sender, KeyEventArgs e)
{
int newvalue = 0;
switch (e.KeyCode)
{
case Keys.Left:
newvalue = panel1.HorizontalScroll.Value
+ panel1.HorizontalScroll.SmallChange;
break;
case Keys.Right:
newvalue = panel1.HorizontalScroll.Value
- panel1.HorizontalScroll.SmallChange;
break;
}

if (newvalue < panel1.HorizontalScroll.Minimum)
newvalue = panel1.HorizontalScroll.Minimum;
else if (newvalue > panel1.HorizontalScroll.Maximum)
newvalue = panel1.HorizontalScroll.Maximum;

panel1.HorizontalScroll.Value = newvalue;
}

void panel2_Paint(object sender, PaintEventArgs e)
{
foreach (Point p in points)
e.Graphics.DrawEllipse(Pens.Red, new Rectangle(p.X - 5, p.Y - 5,
10, 10));
}

List<Point> points = new List<Point>();

void panel2_MouseDown(object sender, MouseEventArgs e)
{
points.Add(e.Location);
panel2.Invalidate();
}
}
 
Back
Top