ImageBoxSample/ImageBox.cs
Download
imageboxsample-part-1.zip
(37.58 KB | 12 August 2010 )
First in a multi part series on creating an image viewer that can be scrolled and zoomed in C#.
Donate
If this site or its services have saved you time, please consider a donation to help with running costs and timely updates.
Contents of imageboxsample-part-1.zip/ImageBoxSample/ImageBox.cs
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
namespace Cyotek.Windows.Forms
{
// Cyotek ImageBox
// Copyright (c) 2010 Cyotek. All Rights Reserved.
// http://cyotek.com
[DefaultProperty("Image")]
public partial class ImageBox : Control
{
#region Private Member Declarations
private BorderStyle _borderStyle;
private int _gridCellSize;
private Color _gridColor;
private Color _gridColorAlternate;
private ImageBoxGridScale _gridScale;
private Bitmap _gridTile;
private System.Drawing.Image _image;
private bool _showGrid;
#endregion Private Member Declarations
#region Public Constructors
public ImageBox()
{
InitializeComponent();
this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw, true);
this.SetStyle(ControlStyles.Selectable, false);
this.UpdateStyles();
this.BackColor = Color.White;
this.TabStop = false;
this.AutoSize = true;
this.GridScale = ImageBoxGridScale.Small;
this.ShowGrid = true;
this.GridColor = Color.Gainsboro;
this.GridColorAlternate = Color.White;
this.GridCellSize = 8;
this.BorderStyle = BorderStyle.FixedSingle;
}
#endregion Public Constructors
#region Events
public event EventHandler BorderStyleChanged;
public event EventHandler GridCellSizeChanged;
public event EventHandler<EventArgs> GridColorAlternateChanged;
public event EventHandler GridColorChanged;
public event EventHandler GridScaleChanged;
public event EventHandler<EventArgs> ImageChanged;
public event EventHandler<EventArgs> ShowCheckerBoxChanged;
#endregion Events
#region Overriden Properties
[Browsable(true), EditorBrowsable(EditorBrowsableState.Always), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible), DefaultValue(true)]
public override bool AutoSize
{
get { return base.AutoSize; }
set
{
if (base.AutoSize != value)
{
base.AutoSize = value;
this.AdjustSize();
}
}
}
[DefaultValue(typeof(Color), "White")]
public override Color BackColor
{
get { return base.BackColor; }
set { base.BackColor = value; }
}
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public override Image BackgroundImage
{
get { return base.BackgroundImage; }
set { base.BackgroundImage = value; }
}
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public override ImageLayout BackgroundImageLayout
{
get { return base.BackgroundImageLayout; }
set { base.BackgroundImageLayout = value; }
}
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public override Font Font
{
get { return base.Font; }
set { base.Font = value; }
}
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public override string Text
{
get { return base.Text; }
set { base.Text = value; }
}
#endregion Overriden Properties
#region Public Overridden Methods
public override Size GetPreferredSize(Size proposedSize)
{
Size size;
if (this.Image != null)
{
int width;
int height;
// get the size of the image
width = this.Image.Size.Width;
height = this.Image.Size.Height;
// add an offset based on padding
width += this.Padding.Horizontal;
height += this.Padding.Vertical;
// add an offset based on the border style
width += this.GetBorderOffset();
height += this.GetBorderOffset();
size = new Size(width, height);
}
else
size = base.GetPreferredSize(proposedSize);
return size;
}
#endregion Public Overridden Methods
#region Protected Overridden Methods
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (components != null)
components.Dispose();
if (_gridTile != null)
{
_gridTile.Dispose();
_gridTile = null;
}
}
base.Dispose(disposing);
}
protected override void OnDockChanged(EventArgs e)
{
base.OnDockChanged(e);
if (this.Dock != DockStyle.None)
this.AutoSize = false;
}
protected override void OnPaddingChanged(System.EventArgs e)
{
base.OnPaddingChanged(e);
this.AdjustSize();
}
protected override void OnPaint(PaintEventArgs e)
{
if (_gridTile != null && this.ShowGrid)
{
// draw the background
for (int x = 0; x < this.ClientSize.Width; x += _gridTile.Size.Width)
{
for (int y = 0; y < this.ClientSize.Height; y += _gridTile.Size.Height)
e.Graphics.DrawImageUnscaled(_gridTile, x, y);
}
}
else
{
using (SolidBrush brush = new SolidBrush(this.BackColor))
e.Graphics.FillRectangle(brush, this.ClientRectangle);
}
// draw the image
if (this.Image != null)
{
e.Graphics.DrawImageUnscaled(this.Image, new Point(this.Padding.Left + this.GetBorderOffset(), this.Padding.Top + this.GetBorderOffset()));
}
// draw the borders
switch (this.BorderStyle)
{
case BorderStyle.FixedSingle:
ControlPaint.DrawBorder(e.Graphics, this.ClientRectangle, this.ForeColor, ButtonBorderStyle.Solid);
break;
case BorderStyle.Fixed3D:
ControlPaint.DrawBorder3D(e.Graphics, this.ClientRectangle, Border3DStyle.Sunken);
break;
}
}
protected override void OnParentChanged(System.EventArgs e)
{
base.OnParentChanged(e);
this.AdjustSize();
}
protected override void OnResize(EventArgs e)
{
if (this.AutoSize)
this.AdjustSize();
base.OnResize(e);
}
#endregion Protected Overridden Methods
#region Public Properties
[Category("Appearance"), DefaultValue(typeof(BorderStyle), "FixedSingle")]
public BorderStyle BorderStyle
{
get { return _borderStyle; }
set
{
if (_borderStyle != value)
{
_borderStyle = value;
this.OnBorderStyleChanged(EventArgs.Empty);
}
}
}
[Category("Appearance"), DefaultValue(8)]
public int GridCellSize
{
get { return _gridCellSize; }
set
{
if (_gridCellSize != value)
{
_gridCellSize = value;
this.OnGridCellSizeChanged(EventArgs.Empty);
}
}
}
[Category("Appearance"), DefaultValue(typeof(Color), "Gainsboro")]
public Color GridColor
{
get { return _gridColor; }
set
{
if (_gridColor != value)
{
_gridColor = value;
this.OnGridColorChanged(EventArgs.Empty);
}
}
}
[Category("Appearance"), DefaultValue(typeof(Color), "White")]
public Color GridColorAlternate
{
get { return _gridColorAlternate; }
set
{
if (_gridColorAlternate != value)
{
_gridColorAlternate = value;
this.OnGridColorAlternateChanged(EventArgs.Empty);
}
}
}
[DefaultValue(typeof(ImageBoxGridScale), "Small"), Category("Appearance")]
public ImageBoxGridScale GridScale
{
get { return _gridScale; }
set
{
if (_gridScale != value)
{
_gridScale = value;
this.OnGridScaleChanged(EventArgs.Empty);
}
}
}
[Category("Appearance"), DefaultValue(null)]
public System.Drawing.Image Image
{
get { return _image; }
set
{
if (_image != value)
{
_image = value;
this.OnImageChanged(EventArgs.Empty);
}
}
}
[DefaultValue(true), Category("Appearance")]
public bool ShowGrid
{
get { return _showGrid; }
set
{
if (_showGrid != value)
{
_showGrid = value;
this.OnShowCheckerBoxChanged(EventArgs.Empty);
}
}
}
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public new bool TabStop
{
get { return base.TabStop; }
set { base.TabStop = value; }
}
#endregion Public Properties
#region Private Methods
private int GetBorderOffset()
{
int offset;
switch (this.BorderStyle)
{
case BorderStyle.Fixed3D:
offset = 2;
break;
case BorderStyle.FixedSingle:
offset = 1;
break;
default:
offset = 0;
break;
}
return offset;
}
private void InitializeGridTile()
{
if (_gridTile != null)
_gridTile.Dispose();
if (this.ShowGrid && this.GridCellSize != 0)
_gridTile = this.CreateGridTileImage(this.GridCellSize, this.GridColor, this.GridColorAlternate);
this.Invalidate();
}
#endregion Private Methods
#region Protected Methods
protected virtual void AdjustSize()
{
if (this.AutoSize)
{
Size size = base.PreferredSize;
base.Size = size;
}
}
protected virtual Bitmap CreateGridTileImage(int cellSize, Color firstColor, Color secondColor)
{
Bitmap result;
int width;
int height;
float scale;
// rescale the cell size
switch (this.GridScale)
{
case ImageBoxGridScale.Medium:
scale = 1.5F;
break;
case ImageBoxGridScale.Large:
scale = 2;
break;
default:
scale = 1;
break;
}
cellSize = (int)(cellSize * scale);
// draw the tile
width = cellSize * 2;
height = cellSize * 2;
result = new Bitmap(width, height);
using (Graphics g = Graphics.FromImage(result))
{
using (SolidBrush brush = new SolidBrush(firstColor))
g.FillRectangle(brush, new Rectangle(0, 0, width, height));
using (SolidBrush brush = new SolidBrush(secondColor))
{
g.FillRectangle(brush, new Rectangle(0, 0, cellSize, cellSize));
g.FillRectangle(brush, new Rectangle(cellSize, cellSize, cellSize, cellSize));
}
}
return result;
}
protected virtual void OnBorderStyleChanged(EventArgs e)
{
this.AdjustSize();
this.Invalidate();
if (this.BorderStyleChanged != null)
this.BorderStyleChanged(this, e);
}
protected virtual void OnGridCellSizeChanged(EventArgs e)
{
this.InitializeGridTile();
if (this.GridCellSizeChanged != null)
this.GridCellSizeChanged(this, e);
}
protected virtual void OnGridColorAlternateChanged(EventArgs e)
{
this.InitializeGridTile();
if (this.GridColorAlternateChanged != null)
this.GridColorAlternateChanged(this, e);
}
protected virtual void OnGridColorChanged(EventArgs e)
{
this.InitializeGridTile();
if (this.GridColorChanged != null)
this.GridColorChanged(this, e);
}
protected virtual void OnGridScaleChanged(EventArgs e)
{
this.InitializeGridTile();
if (this.GridScaleChanged != null)
this.GridScaleChanged(this, e);
}
protected virtual void OnImageChanged(EventArgs e)
{
this.AdjustSize();
this.Invalidate();
if (this.ImageChanged != null)
this.ImageChanged(this, e);
}
protected virtual void OnShowCheckerBoxChanged(EventArgs e)
{
this.InitializeGridTile();
if (this.ShowCheckerBoxChanged != null)
this.ShowCheckerBoxChanged(this, e);
}
#endregion Protected Methods
}
}
