This code ignores image stretching and doesn't support zooming, but if you need a picture box where you can pan the image (or offset it to show only part of the image you load in to it) then here is code that is working great for me!

Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CustomControls
{
	class PannablePictureBox : System.Windows.Forms.PictureBox
	{
		private int _OffsetX = 0;
		private int _OffsetY = 0;
		public int OffsetX
		{
			get
			{
				return _OffsetX;
			}

			set
			{
				if(Image != null)
				{
					if(value > Image.Width - this.Width)
						_OffsetX = Math.Max(Image.Width - this.Width, 0);
					else
						_OffsetX = Math.Max(0, value);
				}
				this.Invalidate();
			}
		}

		public int OffsetY
		{
			get
			{
				return _OffsetY;
			}

			set
			{
				if(Image != null)
				{
					if(value > Image.Height - this.Height)
						_OffsetY = Math.Max(Image.Height - this.Height, 0);
					else
						_OffsetY = Math.Max(0, value);
				}
				this.Invalidate();
			}
		}

		public new System.Drawing.Image Image
		{
			get { return base.Image; }
			set
			{
				base.Image = value;
				if(value == null || _OffsetX > value.Width || _OffsetY > value.Height)
				{
					_OffsetX = 0;
					_OffsetY = 0;
				}
			}
		}

		protected override void OnResize(EventArgs e)
		{
			base.OnResize(e);
			OffsetX = OffsetX; // Make sure the pic still fits
			OffsetY = OffsetY;
		}

		protected override void OnPaint(System.Windows.Forms.PaintEventArgs pe)
		{
			base.OnPaint(pe);
			this.SuspendLayout();
			pe.Graphics.FillRectangle(new System.Drawing.SolidBrush(this.BackColor), pe.ClipRectangle);
			System.Drawing.Rectangle DestinationRect = GetDestinationRectangle(pe.ClipRectangle);
			if(DestinationRect != System.Drawing.Rectangle.Empty)
			{
				pe.Graphics.DrawImage(this.Image, 0, 0, DestinationRect, System.Drawing.GraphicsUnit.Pixel);
			}
			this.ResumeLayout();
		}

		private System.Drawing.Rectangle GetDestinationRectangle(System.Drawing.Rectangle SourceRectangle)
		{
			if(this.Image == null) return System.Drawing.Rectangle.Empty;
			if(SourceRectangle.Top > Image.Height - _OffsetY) return System.Drawing.Rectangle.Empty;
			if(SourceRectangle.Left > Image.Width - _OffsetX) return System.Drawing.Rectangle.Empty;

			int Top = 0;
			int Height = 0;
			int Left = 0;
			int Width = 0;
			Top = SourceRectangle.Top + _OffsetY;
			Height = Math.Min(SourceRectangle.Height, Image.Height - Top);
			Left = SourceRectangle.Left + _OffsetX;
			Width = Math.Min(SourceRectangle.Width, Image.Width - Left);

			return new System.Drawing.Rectangle(Left, Top, Width, Height);			
		}
	}
}