Introduction
A frequent question on developer forums is how to do image panning in .NET. This article aims to show you a very simple way to accomplish panning with your images.
What Is Panning?
When you pan an image, you use the mouse to move to invisible parts of the image. In other words, you drag left on a picture and the right part of the image, that wasn’t visible, becomes visible; when you drag upwards, the bottom part of the image becomes visible. Obviously, this same effect can be accomplished by using scrollbars where you scroll in the appropriate direction to see the parts of the image that is not visible.
Our Project
You will not be creating a very large project today. In fact, it will be a small project, yet very powerful. You will create a panning User Control which can be used in other projects.
Open Visual Studio and create either a Visual Basic or C# Windows Forms Application. You may name it anything you desire; just remember that my object names may differ from yours. Once your project has finished loading, add a User Control. Do this by selecting: Project-> Add User Control. Add the following controls and design it as follows:
ucPan | User Control | Size | 760; 570 |
pnlPan | Panel | BorderStyle | FixedSingle |
Dock | Fill | ||
Size | 746; 537 | ||
picPan | PictureBox | BorderStyle | Fixed3D |
Size | 700; 504 | ||
Image | Any Large Picture |
Figure 1: Design
I have included a picture of a giraffe surrounded by trees. I took it in the Kruger National Park (so beautiful) earlier this year, on holiday in the most beautiful province in South Africa: Mpumalanga.
Code
Declare a Point variable to keep track of where the Mouse button was initially clicked:
C#
private Point pntStart = new Point();
VB.NET
Private pntStart As New Point
Add the following code to the User Control’s Load event:
C#
private void ucPan_Load(object sender, EventArgs e) { pnlPan.AutoScroll = true; picPan.SizeMode = PictureBoxSizeMode.AutoSize; }
VB.NET
Private Sub ucPan_Load(sender As Object, e As EventArgs) _ Handles Me.Load pnlPan.AutoScroll = True picPan.SizeMode = PictureBoxSizeMode.AutoSize End Sub
In the Load event, you simply set the AutoScroll property of the Panel to true and the Picturebox’s SizeMode to AutoSize. This means that the Picturebox will grow or shrink depending on the size of the supplied image.
Add the MouseDown event for the PictureBox:
C#
private void picPan_MouseDown(object sender, MouseEventArgs e) { pntStart = new Point(e.X, e.Y); }
VB.NET
Private Sub picPan_MouseDown(sender As Object, e As _ MouseEventArgs) Handles picPan.MouseDown pntStart = New Point(e.X, e.Y) End Sub
This simply holds the initial starting point. Now, add the MouseMove event:
C#
private void picPan_MouseMove(object sender, MouseEventArgs e) { if (e.Button == System.Windows.Forms.MouseButtons.Left) { int X = (pntStart.X - e.X); int Y = (pntStart.Y - e.Y); pnlPan.AutoScrollPosition = new Point((X - pnlPan.AutoScrollPosition.X), (Y - pnlPan.AutoScrollPosition.Y)); } }
VB.NET
Private Sub picPan_MouseMove(sender As Object, e As _ MouseEventArgs) Handles picPan.MouseMove If e.Button = Windows.Forms.MouseButtons.Left Then Dim X As Integer = (pntStart.X - e.X) Dim Y As Integer = (pntStart.Y - e.Y) pnlPan.AutoScrollPosition = New Point((X - pnlPan.AutoScrollPosition.X), _ (Y - pnlPan.AutoScrollPosition.Y)) End If End Sub
In the MouseMove event, you simply shift the image up to where the button was clicked down in the MouseDown event.
Build your project. After your project is built successfully, your User Control will be ready to use. But first, you must add it from the Toolbox onto your form, as shown in Figure 2.
Figure 2: User Control inside the Toolbox
After you have added the User Control to your form, you can run your project. It will work as shown in Figure 3:
Figure 3: Running with borders displayed
If you want to eliminate the borders, add the following code in Form1.
C#
protected override void DefWndProc(ref Message m) { if (m.Msg != 131) base.DefWndProc(ref m); }
VB.NET
Protected Overrides Sub DefWndProc(ByRef m As Message) If m.Msg <> 131 Then MyBase.DefWndProc(m) End If
This overrides the DefWndProc system function to send a message to hide the borders. Figure 4 shows the result.
Figure 4: Running without borders
Conclusion
Playing with pictures is fun. I hope you have enjoyed today’s article and that you have learned from it.