Introduction
This control allows you to add Thumbnail by dragdrop image from desktop and preview the Image by double-clicking on Thumbnail.
Using the Code
At first, declare an "ImageExtensions
" List to make sure all files added to Control are Image Type.
private List<string> ImageExtensions = new List<string>
{ ".JPG", ".JPE", ".BMP", ".GIF", ".PNG" };
The DragDrop
system is just simple, use DragEnter
event to set an effect when user drags files to control and DragDrop
event to deal with the files.
void ThumbnailViewerControl_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
e.Effect = DragDropEffects.Copy;
else
e.Effect = DragDropEffects.None;
}
void ThumbnailViewerControl_DragDrop(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
AddImage(files);
}
}
When dropped files to control, the AddImage
method will add image to List
as binary and then show a thumbnail on Panel
by MakeThumbnail
method.
public void AddImage(string[] files)
{
this.Cursor = Cursors.WaitCursor;
byte[] binary;
for (int i = 0; i < files.Count(); i++)
{
if (ImageExtensions.Contains(Path.GetExtension(files[i]).ToUpperInvariant()))
{
binary = File.ReadAllBytes(files[i]);
ImageList.Add(binary);
MakeThumbnail(binary);
GC.GetTotalMemory(true);
}
}
this.Cursor = Cursors.Default;
}
public void MakeThumbnail(byte[] binary)
{
PictureBox thumb = new PictureBox();
thumb.MaximumSize = new Size(128, 128);
thumb.MinimumSize = new Size(128, 128);
thumb.Size = new Size(128, 128);
thumb.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
thumb.SizeMode = PictureBoxSizeMode.Zoom;
thumb.MouseEnter += new EventHandler(thumb_MouseEnter);
thumb.MouseLeave += new EventHandler(thumb_MouseLeave);
thumb.DoubleClick += new EventHandler(thumb_DoubleClick);
MemoryStream ms = new MemoryStream();
thumb.Image = Image.FromStream(new MemoryStream(binary))
.GetThumbnailImage(thumb.Width - 2, thumb.Height - 2, null, new IntPtr());
ms.Close();
this.Controls.Add(thumb);
}
Now, thumbnails are added to Panel
, but to make it more prettier when user moves mouse cursor over it, use MouseEnter
event to draw a border around thumbnail and clear border when Mouse
leaves by MouseLeave
event.
void thumb_MouseLeave(object sender, EventArgs e)
{
((PictureBox)sender).Invalidate();
}
void thumb_MouseEnter(object sender, EventArgs e)
{
var rc = ((PictureBox)sender).ClientRectangle;
rc.Inflate(-2, -2);
ControlPaint.DrawBorder(((PictureBox)sender).CreateGraphics()
, ((PictureBox)sender).ClientRectangle, Color.Red, ButtonBorderStyle.Solid);
ControlPaint.DrawBorder3D(((PictureBox)sender).CreateGraphics()
, rc, Border3DStyle.Bump);
}
Thumbnail is small, right? So when user wants to "preview" full size image, let's show them a preview form created on thumbnail's mouse doubleclick event.
void thumb_DoubleClick(object sender, EventArgs e)
{
Form previewForm = new Form();
previewForm.FormBorderStyle = FormBorderStyle.SizableToolWindow;
previewForm.MinimizeBox = false;
previewForm.Size = new System.Drawing.Size(800, 600);
previewForm.StartPosition = FormStartPosition.CenterScreen;
PictureBox view = new PictureBox();
view.Dock = DockStyle.Fill;
int index = this.Controls.GetChildIndex((PictureBox)sender);
view.Image = BinaryToImage(ImageList[index]);
view.SizeMode = PictureBoxSizeMode.Zoom;
previewForm.Controls.Add(view);
previewForm.ShowDialog();
}
On the event above, when doubleclicked on thumbnail, we must convert the binary data back to an Image
, this method will do that job.
public static Image BinaryToImage(byte[] binaryData)
{
if (binaryData == null) return null;
byte[] buffer = binaryData.ToArray();
MemoryStream memStream = new MemoryStream();
memStream.Write(buffer, 0, buffer.Length);
return Image.FromStream(memStream);
}
That's all !!! This is just a tip for beginners, I recommend you add more methods to it like:
- Delete Image method: Delete a selecting thumbnail, be careful with
Panel
control index and List
item index. BackgroundWorker
: The UI will freeze when you add a large number of images, so a backgroundworker will handle it. - Threading: Large size image will consuming time. Try something like Parallel looping to make the process faster.
Thanks for reading and feel free to comment.