[ProvideProperty("AfterZoomImage", typeof(PictureBox))]
[ProvideProperty("ZoomFactor", typeof(PictureBox))]
public partial class ImageZoomProvider : Component, IExtenderProvider
{
public ImageZoomProvider()
{
InitializeComponent();
AnchorStyle = AnchorPoint.TopLeft;
}
// Theses will hold references to extended objects.
private Hashtable pictureBoxes = new Hashtable();
private Hashtable afterZoomImages = new Hashtable();
#region "AfterZoomImage"
[DefaultValue(null)]
[Description("The image that will be used to display the zoomed image, if set to null the value of the PictureBox.Image property will be used instead")]
[Category("ImageZoomProvider")]
public Image GetAfterZoomImage(PictureBox pictureBox)
{
if (pictureBox == null)
{
throw new ArgumentNullException("pictureBox");
}
Image imageAfterZoom = null;
if (afterZoomImages.Contains(pictureBox))
{
imageAfterZoom = afterZoomImages[pictureBox] as Image;
}
return imageAfterZoom;
}
public void SetAfterZoomImage(PictureBox pictureBox, Image afterZoomImage)
{
if (pictureBox == null)
{
throw new ArgumentNullException("pictureBox");
}
if (afterZoomImage == null)
{
if (afterZoomImages.Contains(pictureBox))
afterZoomImages.Remove(pictureBox);
}
else
afterZoomImages[pictureBox] = afterZoomImage;
}
#endregion
#region IExtenderProvider Members
public bool CanExtend(object extendee)
{
return extendee is PictureBox;
}
#endregion
#region "ZoomFactor"
[DefaultValue(1)]
[Description("The factor by which the Image will be zoomed")]
[Category("ImageZoomProvider")]
public int GetZoomFactor(PictureBox pictureBox)
{
if (pictureBox == null)
{
throw new ArgumentNullException("pictureBox");
}
object value = pictureBoxes[pictureBox];
if (value != null)
{
return (int)value;
}
else
return ImageZoomProvider.NoZoom;
}
public void SetZoomFactor(PictureBox pictureBox, int zoomFactor)
{
if (pictureBox == null)
{
throw new ArgumentNullException("pictureBox");
}
// To Do validate Zoom Factor here.
if (zoomFactor < 1)
{
throw new ArgumentException("ZoomFactor should be greater or equal to 1");
}
object oldZoomFactor = pictureBoxes[pictureBox];
if (oldZoomFactor == null)
{
// No zoom factor was associated to this control. Then add zoom factor and set handlers.
if (zoomFactor != NoZoom)
{
pictureBoxes[pictureBox] = zoomFactor;
if (ZoomOnClick)
{
pictureBox.Click += new EventHandler(OnPictureBoxClick);
}
else
{
pictureBox.MouseEnter += new EventHandler(OnPictureBoxMouseEnter);
pictureBox.MouseLeave += new EventHandler(OnPictureBoxMouseLeave);
}
}
}
else
{
int oldZoomValue = (int)oldZoomFactor;
// Zomm Factor has changed ?
if (oldZoomValue != zoomFactor)
{
// update the zoom factor.
pictureBoxes[pictureBox] = zoomFactor;
if (zoomFactor == NoZoom)
{
// Remove zoom logic.
pictureBoxes.Remove(pictureBox);
if (ZoomOnClick)
{
pictureBox.Click -= new EventHandler(OnPictureBoxClick);
}
else
{
pictureBox.MouseEnter -= new EventHandler(OnPictureBoxMouseEnter);
pictureBox.MouseLeave -= new EventHandler(OnPictureBoxMouseLeave);
}
}
}
}
}
#endregion
#region "Public Properties"
[DefaultValue(100)]
[Description("When ZoomOnClick property is false, this value is used as an initial delay debore showing the zoomed picture")]
[Category("ImageZoomProvider")]
public int ZoomDelay
{
get
{
return timer.Interval;
}
set
{
timer.Interval = value;
}
}
[DefaultValue(100)]
[Description("When UseAnimation is set to true, this value controls how fast the animation is")]
[Category("ImageZoomProvider")]
public int AnimationInterval
{
get
{
return timerAnimation.Interval;
}
set
{
timerAnimation.Interval = value;
}
}
private AnchorPoint anchorStyle = AnchorPoint.TopLeft;
[Category("ImageZoomProvider")]
[DefaultValue(AnchorPoint.TopLeft)]
public AnchorPoint AnchorStyle
{
get { return anchorStyle; }
set { anchorStyle = value; }
}
private int border = 0;
[Category("ImageZoomProvider")]
[DefaultValue(0)]
[Description("if value is different than 0, a border rectangle will be drawn around the zoomed image")]
public int Border
{
get { return border; }
set { border = value; }
}
[Category("ImageZoomProvider")]
[DefaultValue(false)]
[Description("if set to true, the image will grow in steps")]
public bool UseAnimation { get; set; }
private ImageZoomForm zoomForm = null;
private static int noZoom = 1;
public static int NoZoom
{
get { return ImageZoomProvider.noZoom; }
}
private bool zoomOnClick = false;
[DefaultValue(false)]
[Description("If set to true then zoom will be triggered by mouse click, otherwise mouse hover will trigger the zoom")]
[Category("ImageZoomProvider")]
public bool ZoomOnClick
{
get { return zoomOnClick; }
set
{
if (zoomOnClick != value)
{
zoomOnClick = value;
UpdatePictureBoxesHandlers();
}
}
}
#endregion
private void UpdatePictureBoxesHandlers()
{
if (pictureBoxes != null)
{
foreach (PictureBox pictureBox in pictureBoxes.Keys)
{
if (ZoomOnClick)
{
pictureBox.MouseEnter -= new EventHandler(OnPictureBoxMouseEnter);
pictureBox.MouseLeave -= new EventHandler(OnPictureBoxMouseLeave);
pictureBox.Click += new EventHandler(OnPictureBoxClick);
}
else
{
pictureBox.Click -= new EventHandler(OnPictureBoxClick);
pictureBox.MouseEnter += new EventHandler(OnPictureBoxMouseEnter);
pictureBox.MouseLeave += new EventHandler(OnPictureBoxMouseLeave);
}
}
}
}
public ImageZoomProvider(IContainer container)
{
container.Add(this);
InitializeComponent();
}
void OnPictureBoxClick(object sender, EventArgs e)
{
timer.Tag = sender;
// No delay required. call timer.Tick event Handler.
ShowZoomedPicture(timer, EventArgs.Empty);
}
void OnPictureBoxMouseLeave(object sender, EventArgs e)
{
timer.Tag = null;
timer.Stop();
}
void OnPictureBoxMouseEnter(object sender, EventArgs e)
{
timer.Tag = sender;
timer.Start();
}
private void ShowZoomedPicture(object sender, EventArgs e)
{
// Show zoomed window here.
timer.Stop();
if (pictureBoxes.Contains(timer.Tag))
{
int zoomFactor = (int)pictureBoxes[timer.Tag];
PictureBox pictureBox = (PictureBox)timer.Tag;
if (zoomForm == null)
zoomForm = new ImageZoomForm();
// Set zoom properties.
zoomForm.InitialSize = pictureBox.Size;
zoomForm.Border = Border;
zoomForm.ZoomFactor = zoomFactor;
Image afterZoomImage = GetAfterZoomImage(pictureBox);
if (afterZoomImage == null)
afterZoomImage = pictureBox.Image;
if (zoomForm.Image != afterZoomImage)
zoomForm.Image = afterZoomImage;
if (!UseAnimation)
{
zoomForm.Size = new Size(zoomFactor * pictureBox.Size.Width,
zoomFactor * pictureBox.Size.Height);
ControlAnchorer.AnchorControl(zoomForm, pictureBox,AnchorStyle);
zoomForm.Show();
}
else
{
if (AnchorStyle == AnchorPoint.OverlapCenters || AnchorStyle == AnchorPoint.TopCenter)
{
zoomForm.Size = new Size(zoomFactor * pictureBox.Size.Width,
zoomFactor * pictureBox.Size.Height);
ControlAnchorer.AnchorControl(zoomForm, pictureBox, AnchorStyle);
}
zoomForm.Size = new Size(pictureBox.Size.Width,
pictureBox.Size.Height);
if(AnchorStyle != AnchorPoint.OverlapCenters && AnchorStyle != AnchorPoint.TopCenter)
ControlAnchorer.AnchorControl(zoomForm, pictureBox, AnchorStyle);
originalSize = zoomForm.Size;
growSize = new Size((zoomFactor -1) * originalSize.Width /3,( zoomFactor-1) * originalSize.Height/3 );
counter = 0;
timerAnimation.Tag = pictureBox;
timerAnimation.Start();
zoomForm.Show();
}
}
}
private Size originalSize = Size.Empty;
private Size growSize = Size.Empty;
private int counter = 0;
private void timerAnimation_Tick(object sender, EventArgs e)
{
if (counter < 3)
{
zoomForm.Size += growSize;
//ControlAnchorer.AnchorControl(zoomForm, timerAnimation.Tag as Control, AnchorStyle);
counter++;
}
else
{
timerAnimation.Stop();
}
}
internal class ImageZoomForm : Form
{
private int border = 0;
private Size initialSize;
private int zoomFactor = 1;
private PictureBox zoomedPicture = null;
public int Border
{
get { return border; }
set
{
border = value;
UpdateZoomedPictureSize();
}
}
public Size InitialSize
{
get { return initialSize; }
set
{
initialSize = value;
Size = value;
UpdateZoomedPictureSize();
}
}
public int ZoomFactor
{
get { return zoomFactor; }
set
{
zoomFactor = value;
}
}
private void UpdateZoomedPictureSize()
{
if (zoomedPicture != null)
{
zoomedPicture.Size = new Size(initialSize.Width - (border * 2),
initialSize.Height - (border * 2));
zoomedPicture.Location = new Point(border, border);
}
}
public ImageZoomForm()
{
TopMost = true;
BackColor = Color.Black;
ShowInTaskbar = false;
StartPosition = FormStartPosition.Manual;
FormBorderStyle = FormBorderStyle.None;
zoomedPicture = new PictureBox();
zoomedPicture.SizeMode = PictureBoxSizeMode.Zoom;
zoomedPicture.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Bottom;
zoomedPicture.Click += new EventHandler(OnClick);
Click += new EventHandler(OnClick);
LostFocus += new EventHandler(OnLostFocus);
Controls.Add(zoomedPicture);
}
void OnLostFocus(object sender, EventArgs e)
{
Hide();
}
void OnClick(object sender, EventArgs e)
{
PictureBox pictureBox = sender as PictureBox;
if (pictureBox != null)
{
((Form)pictureBox.Parent).Hide();
}
else
((Form)sender).Hide();
}
public Image Image
{
get
{
return zoomedPicture.Image;
}
set
{
zoomedPicture.Image = value;
}
}
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.Escape)
{
DialogResult = System.Windows.Forms.DialogResult.OK;
Hide();
return true;
}
else
{
return base.ProcessCmdKey(ref msg, keyData);
}
}
}
}
References: