You could easily make the static picturebox, that you are already using for magnification, dynamically show/hide/move based on user input. Such as onMouseEnter it could move to the desired location (based on the mouse), onMouseMove it would follow the mouse, and onMouseLeave it would hide.
Just handle those events for the parent picturebox, and it should work great. Just be sure to offset the Magnified picturebox from the cursor a pixel or two. If you make the magnified picturebox show under the cursor, you will get into a loop because the onMouseLeave event will fire on the parent picturebox when the magnified one shows underneath, which would cause the magnified picturebox to disappear, which would trigger onMouseEnter and show it again....
Here is a quick and dirty sample (hint: dont go near the edges of the form)
Just create a form with a picturebox (pictureBox1) that has DockStyle=Full, and another smaller picturebox with Visible=false. Then give pictureBox1 a Background image.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.pictureBox1.MouseEnter += (sender, args) => this.pictureBox2.Show();
this.pictureBox1.MouseLeave += (sender, args) => this.pictureBox2.Hide();
this.pictureBox1.MouseMove += (sender, args) => DoMagnification();
}
private void DoMagnification()
{
var oldImage = this.pictureBox2.BackgroundImage;
if (oldImage != null)
oldImage.Dispose();
var position = this.pictureBox1.PointToClient(Cursor.Position);
var pboxWidth = this.pictureBox2.Width / 2;
var pboxHeight = this.pictureBox2.Height / 2;
Bitmap image = new Bitmap(this.pictureBox1.Width, this.pictureBox1.Height);
this.pictureBox1.DrawToBitmap(image, this.pictureBox1.Bounds);
Rectangle cloneRect = new Rectangle(Math.Max(position.X, 0), Math.Max(position.Y, 0), pboxWidth, pboxHeight);
if (cloneRect.Width + cloneRect.X > image.Width)
cloneRect.X -= (image.Width - cloneRect.Width);
if (cloneRect.Height + cloneRect.Y > image.Height)
cloneRect.Y -= (image.Height - cloneRect.Height);
System.Drawing.Imaging.PixelFormat format =
image.PixelFormat;
Bitmap cloneBitmap = image.Clone(cloneRect, format);
using (var graphics = CreateGraphics())
graphics.DrawImage(cloneBitmap, 0, 0);
this.pictureBox2.BackgroundImage = cloneBitmap;
this.pictureBox2.BackgroundImageLayout = ImageLayout.Zoom;
this.pictureBox2.Location = OffsetByAFewPixels(position);
}
private Point OffsetByAFewPixels(Point location)
{
return new Point(location.X + 1, location.Y + 1);
}
}