It is an example of creating custom controls for getting graphic data from database.
Introduction
This is example of creating custom controls for getting graphic data from database. I'm going to make control and then, test my control in a Windows application. I have developed some custom properties for my control.
In standard component bar, we don't have any component for getting graphic data from database like Gallery. But we can create component themselves using some standard component.
This is a simple C# control to get images from data base.
The first time I started to work with .NET .I saw that standard component's panel doesn't have a control which could be shown images from database as gallery and I decided to create my own control...
(Used material NET 2.0 Windows Forms and Custom Controls in C# by Matthew MacDonald)
Using the code
The project is designed as a custom control. In article "PictureBox with zooming and scrolling", there is described how to install and use such a control, or have a look at the different articles about that topic in CodeProject, for example "Writing your Custom Control: step by step" by Alexandr Khilov.
Methods / Properties
The control provides seven designer related properties:
DataSource
: Data source of data base.
PicFieldName
: Data field of Image.
PicTitleFieldName
: Data field of Image's title.
Dimension
: Space among columns.
IconHeight
: Icon's height
IconWidth
: Icon's width
Spacing
:
Space among rows.
Events
There is one event in the class onDoubleClick. The event is arisen if the mouse left button clicks twice and show full size image.
Helper classes
The class exPictureBox is extention of PictureBox used for saveing some propertis of image.
The class PictureSelectedEventArgs is derived from System.EventArgs
. I used it for selection event of image properties. The class PictureDoubleClickEventArgs is derived from System.
EventArgs
used it for double click event of image properties.
The class PicFieldConverter is derived from System.ComponentModel.StringConverter
. I used it to convert properties.
The class PicNameFieldConverter is derived from System.ComponentModel.StringConverter
used it to convert properties.
The class NamedImage is simple class for saveing name propertis of image.
In the code you can see how to work with classes.
Building the Control
1. Open the Visual Studio and create a new project. Your project must be based on the Windows Control Library template. Call your project PicDB and click OK.
2. Once you have your project open, delete the UserControl from the project.
3. Now go to the 'Project' menu: Project->Add User Control... and select the Custom Control template there. 'Custom Control' is what we need in this case. You call it PicDB
and click OK. A new Custom control has been added to your project.
4. The first thing we must do here is to change the base class of the PicDB
:
Override the following line:
public partial class PicDB : UserControl
By this one:
public class PicDB : UserControl
Add attribute for our control (Before prepare icon for our control and named it _PicDB.bmp)
[ToolboxBitmap(typeof(PicDB), "_PicDB.bmp")]
5. Set necessary namespaces.
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using System.Threading;
6. Now create some custom properties and auxiliary classes for our control. This is done by inserting the following code inside the PicDB class:
private IContainer components;
private int dimension;
private int border = 5;
private int indexOfImage = 0;
private int spacing;
private Panel pnlPictures;
private ArrayList images = new ArrayList();
private ArrayList exImages = new ArrayList();
private DataSet dataset = null;
private DataColumnCollection dataColumn = null;
private BindingSource bindingSource = null;
private string imageTitle = "";
private int iconHeight;
private int iconWidth;
private int ControlColumn;
private ToolTip toolTipImage;
private Panel pnToolBar;
private ToolBar toolBar;
private ImageList imgList;
private ToolBarButton tbntNext;
private ToolBarButton tbntPrior;
private ToolBarButton tbntLast;
private ToolBarButton tbntFirst;
private OpenFileDialog openFileDialog;
private delegate void PictureSelectedDelegate(object sender, PictureSelectedEventArgs e);
private event PictureSelectedDelegate PictureSelected;
private class PictureSelectedEventArgs : EventArgs
{
public string imgName;
public Image Image;
public PictureSelectedEventArgs(String imageName, Image image)
{
imgName = imageName;
Image = image;
}
}
private class exPictureBox : PictureBox
{
private Image img = null;
public Image ImageFullSize
{
get { return img; }
set
{
img = value;
}
}
}
private class PictureDoubleClickEventArgs : EventArgs
{
public string imgName;
public Image Image;
public PictureDoubleClickEventArgs(String imageName, Image image)
{
imgName = imageName;
Image = image;
}
}
private exPictureBox picSelected;
private void onPicClick(object sender, EventArgs e)
{
if (sender != picSelected)
{
if (picSelected != null)
{
picSelected.BorderStyle = BorderStyle.FixedSingle;
}
}
picSelected = (exPictureBox)sender;
picSelected.BorderStyle = BorderStyle.Fixed3D;
PictureSelectedEventArgs args = new PictureSelectedEventArgs(picSelected.Tag.ToString(), picSelected.Image);
indexOfImage = System.Convert.ToInt32(picSelected.Tag) + 1;
if (PictureSelected != null)
{
PictureSelected(this, args);
}
OnClick(args);
}
private void onDoubleClick(object sender, EventArgs e)
{
if (picSelected.Image != null)
{
Form ModalForm = new Form();
PictureBox PicImg = new PictureBox();
PicImg.Image = picSelected.ImageFullSize;
PicImg.Dock = DockStyle.Fill;
ModalForm.Size = new Size(picSelected.ImageFullSize.Width, picSelected.ImageFullSize.Height + 25);
ModalForm.Controls.Add(PicImg);
ModalForm.ShowInTaskbar = false;
ModalForm.FormBorderStyle = FormBorderStyle.SizableToolWindow;
ModalForm.ShowDialog();
OnDoubleClick(e);
ModalForm.Dispose();
}
}
static ArrayList _PicField = new ArrayList();
static ArrayList _PicNameField = new ArrayList();
[Description("Height of Images."),
DefaultValue(120),
Category("Images")]
public int IconHeight
{
get
{
return iconHeight;
}
set
{
iconHeight = value;
}
}
[Browsable(true),
Description("Width of Images."),
DefaultValue(80),
Category("Images")]
public int IconWidth
{
get
{
return iconWidth;
}
set
{
iconWidth = value;
}
}
[Browsable(true)]
[DefaultValue(100)]
[Category("Images")]
[Description("Dimension amoung Images.")]
public int Dimension
{
get
{
return dimension;
}
set
{
dimension = value;
}
}
[Browsable(true)]
[DefaultValue(80)]
[Category("Images")]
[Description("Spacing amoung Images.")]
public int Spacing
{
get
{
return spacing;
}
set
{
spacing = value;
}
}
private DataSet DataSet
{
get { return dataset; }
set
{
dataset = value;
if (dataset != null)
{
_PicField.Clear();
_PicNameField.Clear();
for (int jj = 0; jj <= dataset.Tables[0].Columns.Count - 1; jj++)
{
Type t = dataset.Tables[0].Columns[jj].DataType;
if (t.FullName == "System.Byte[]")
{
_PicField.Add(dataset.Tables[0].Columns[jj].ToString());
}
else
{
_PicNameField.Add(dataset.Tables[0].Columns[jj].ToString());
}
}
}
else
{
_PicField.Clear();
_PicNameField.Clear();
}
}
}
private DataColumnCollection DataColumn
{
get { return dataColumn; }
set
{
dataColumn = value;
}
}
public class PicFieldConverter : StringConverter
{
public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
{
return true;
}
public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
{
return true;
}
public override System.ComponentModel.TypeConverter.StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
{
return new StandardValuesCollection(_PicField);
}
}
public class PicNameFieldConverter : StringConverter
{
public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
{
return true;
}
public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
{
return true;
}
public override
System.ComponentModel.TypeConverter.StandardValuesCollection
GetStandardValues(ITypeDescriptorContext context)
{
return new StandardValuesCollection(_PicNameField);
}
}
private string FieldName;
[Browsable(true)]
[Description("Picture field")]
[TypeConverter(typeof(PicFieldConverter))]
[Category("Data")]
public string PicFieldName
{
get
{
string S = "";
if (FieldName != null)
{
if (this.DataSet != null)
S = FieldName;
else
S = "";
}
return S;
}
set { FieldName = value; }
}
private string FieldNameTitle;
[Browsable(true)]
[Description("Pictures title")]
[TypeConverter(typeof(PicNameFieldConverter))]
[Category("Data")]
public string PicTitleFieldName
{
get
{
string S = "";
if (FieldNameTitle != null)
{
if (this.DataSet != null)
S = FieldNameTitle;
else
S = "";
}
return S;
}
set { FieldNameTitle = value; }
}
[Browsable(true)]
[Description("Pictures's Data Source")]
[Category("Data")]
public BindingSource DataSource
{
get { return bindingSource; }
set
{
bindingSource = value;
if (value != null)
{
this.DataSet = (DataSet)bindingSource.DataSource;
if (DataSet != null)
{
this.DataColumn = (DataColumnCollection) DataSet.Tables[0].Columns;
}
}
}
}
private class NamedImage
{
public Image Image;
public string imgName;
public NamedImage(Image image, string imageName)
{
Image = image;
imgName = imageName;
}
}
private void GetImagesDB()
{
lock (images)
{
int k = 0;
images.Clear();
int counT;
try
{
counT = dataset.Tables[0].Rows.Count;
}
catch
{
counT = -1;
}
if (counT > 0)
do
{
try
{
Image img = null;
if (PicFieldName != "")
{
byte[] blob = (byte[])(dataset.Tables[0].Rows[k][PicFieldName]);
MemoryStream ms = new MemoryStream(blob, 0, blob.Length);
img = Image.FromStream(ms);
ms.Dispose();
if (PicTitleFieldName != "")
{
imageTitle = dataset.Tables[0].Rows[k][PicTitleFieldName].ToString();
}
else
{
imageTitle = "";
}
images.Add(new NamedImage(img, imageTitle));
k++;
}
}
catch
{
imageTitle = "";
images.Add(new NamedImage(null, imageTitle));
k++;
}
}
while (k <= counT - 1);
exImages.Clear();
}
pnlPictures.Invoke(new MethodInvoker(this.UpdateDisplay));
}
private void GetImages()
{
Thread getThread = new Thread(new ThreadStart(this.GetImagesDB));
getThread.Start();
}
private void UpdateDisplay()
{
if ((IconWidth != 0) && (IconHeight != 0))
{
pnlPictures.SuspendLayout();
foreach (Control ctrl in pnlPictures.Controls)
{
ctrl.Dispose();
}
pnlPictures.Controls.Clear();
int row = border, col = border;
int imgW, imgH = 0;
double reSize, reSize1 = 0;
int i = 0;
lock (images)
{
foreach (NamedImage image in images)
{
exPictureBox pic = new exPictureBox();
ControlColumn = (int)(Math.Floor((double)(Width / (this.IconWidth + 10))));
if (image.Image != null)
{
reSize = Math.Round(this.IconHeight / ((double)(image.Image.Height)), 3);
reSize1 = Math.Round(this.IconWidth / ((double)(image.Image.Width)), 3);
if (reSize >= reSize1)
reSize = reSize1;
imgW = (int)(Math.Ceiling(image.Image.Width * reSize));
imgH = (int)(Math.Ceiling(image.Image.Height * reSize));
pic.Image = new Bitmap(image.Image, new Size(imgW, imgH));
pic.ImageFullSize = image.Image;
}
else
{
pic.Image = null;
pic.ImageFullSize = null;
}
this.toolTipImage.SetToolTip(pic, image.imgName);
pic.Tag = i;
i++;
pic.Size = new Size(this.IconWidth, this.IconHeight);
pic.Location = new Point(col, row);
pic.BorderStyle = BorderStyle.FixedSingle;
exImages.Add(pic);
pic.DoubleClick += new EventHandler(onDoubleClick);
pic.Click += new EventHandler(onPicClick);
pnlPictures.Controls.Add(pic);
col += (int)Math.Ceiling((double)((dimension + IconHeight* IconWidth / IconHeight));
if ((col + spacing + border + IconWidth) > Width)
{
col = border;
row += IconHeight + spacing;
}
}
if (indexOfImage > 0)
{
exPictureBox px = new exPictureBox();
px = (exPictureBox)exImages[indexOfImage - 1];
picSelected = px;
px.BorderStyle = BorderStyle.Fixed3D;
}
}
pnlPictures.ResumeLayout();
}
}
protected override void OnSizeChanged(EventArgs e)
{
base.OnSizeChanged(e);
Invalidate();
}
public PicDB()
{
InitializeComponent();
}
int pos = 0;
private void OnMouseWheel(object sender, MouseEventArgs e)
{
pos = pnlPictures.VerticalScroll.Value;
if (e.Delta < 5)
{
if (pos < this.Height)
{
pos += 10;
}
pnlPictures.VerticalScroll.Value = pos;
}
else
{
pos -= 10;
if (pos < 0)
{
pos = 0;
}
else
pnlPictures.VerticalScroll.Value = pos;
}
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose(disposing);
}
#region Component Designer generated code
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(PicDB));
this.pnlPictures = new System.Windows.Forms.Panel();
this.pnToolBar = new System.Windows.Forms.Panel();
this.toolBar = new System.Windows.Forms.ToolBar();
this.tbntNext = new System.Windows.Forms.ToolBarButton();
this.tbntPrior = new System.Windows.Forms.ToolBarButton();
this.tbntLast = new System.Windows.Forms.ToolBarButton();
this.tbntFirst = new System.Windows.Forms.ToolBarButton();
this.imgList = new System.Windows.Forms.ImageList(this.components);
this.toolTipImage = new System.Windows.Forms.ToolTip(this.components);
this.openFileDialog = new System.Windows.Forms.OpenFileDialog();
this.pnToolBar.SuspendLayout();
this.SuspendLayout();
this.pnlPictures.AllowDrop = true;
this.pnlPictures.AutoScroll = true;
this.pnlPictures.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.pnlPictures.Dock = System.Windows.Forms.DockStyle.Fill;
this.pnlPictures.Location = new System.Drawing.Point(0, 32);
this.pnlPictures.Name = "pnlPictures";
this.pnlPictures.Size = new System.Drawing.Size(179, 135);
this.pnlPictures.TabIndex = 0;
this.pnToolBar.Controls.Add(this.toolBar);
this.pnToolBar.Dock = System.Windows.Forms.DockStyle.Top;
this.pnToolBar.Location = new System.Drawing.Point(0, 0);
this.pnToolBar.Name = "pnToolBar";
this.pnToolBar.Size = new System.Drawing.Size(179, 32);
this.pnToolBar.TabIndex = 0;
this.toolBar.Appearance = System.Windows.Forms.ToolBarAppearance.Flat;
this.toolBar.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.toolBar.Buttons.AddRange(new System.Windows.Forms.ToolBarButton[] {
this.tbntNext,
this.tbntPrior,
this.tbntLast,
this.tbntFirst});
this.toolBar.ButtonSize = new System.Drawing.Size(16, 16);
this.toolBar.Dock = System.Windows.Forms.DockStyle.Fill;
this.toolBar.DropDownArrows = true;
this.toolBar.ImageList = this.imgList;
this.toolBar.Location = new System.Drawing.Point(0, 0);
this.toolBar.Name = "toolBar";
this.toolBar.ShowToolTips = true;
this.toolBar.Size = new System.Drawing.Size(179, 29);
this.toolBar.TabIndex = 0;
this.toolBar.ButtonClick += new System.Windows.Forms.ToolBarButtonClickEventHandler(this.toolBar_ButtonClick);
this.tbntNext.ImageIndex = 0;
this.tbntNext.Name = "tbntNext";
this.tbntPrior.ImageIndex = 1;
this.tbntPrior.Name = "tbntPrior";
this.tbntLast.ImageIndex = 2;
this.tbntLast.Name = "tbntLast";
this.tbntFirst.ImageIndex = 3;
this.tbntFirst.Name = "tbntFirst";
this.imgList.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imgList.ImageStream")));
this.imgList.TransparentColor = System.Drawing.Color.Transparent;
this.imgList.Images.SetKeyName(0, "back.gif");
this.imgList.Images.SetKeyName(1, "forward.gif");
this.imgList.Images.SetKeyName(2, "first.gif");
this.imgList.Images.SetKeyName(3, "last.gif");
this.openFileDialog.Filter = "Image Files | *.JPG;*.GIF;*.BMP";
this.Controls.Add(this.pnlPictures);
this.Controls.Add(this.pnToolBar);
this.Name = "PicDB";
this.Size = new System.Drawing.Size(179, 167);
this.MouseWheel += new System.Windows.Forms.MouseEventHandler(this.OnMouseWheel);
this.Paint += new System.Windows.Forms.PaintEventHandler(this.PicDB_Paint);
this.pnToolBar.ResumeLayout(false);
this.pnToolBar.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private void PicDB_Paint(object sender, PaintEventArgs e)
{
GetImages();
this.MouseWheel -= new System.Windows.Forms.MouseEventHandler(this.OnMouseWheel);
this.MouseWheel += new System.Windows.Forms.MouseEventHandler(this.OnMouseWheel);
}
private void toolBar_ButtonClick(object sender, ToolBarButtonClickEventArgs e)
{
exPictureBox px = new exPictureBox();
if (DataSet != null)
{
if (e.Button == toolBar.Buttons[1])
{
if (indexOfImage >= 0 && indexOfImage < exImages.Count)
{
px = (exPictureBox)exImages[indexOfImage];
picSelected = px;
px.BorderStyle = BorderStyle.Fixed3D;
}
if (indexOfImage > 0 && indexOfImage < exImages.Count)
{
px = (exPictureBox)exImages[indexOfImage - 1];
px.BorderStyle = BorderStyle.FixedSingle;
}
if (indexOfImage < exImages.Count)
indexOfImage++;
}
if (e.Button == toolBar.Buttons[0])
{
if (indexOfImage <= exImages.Count && indexOfImage > 0)
{
if (indexOfImage > 1)
indexOfImage--;
px = (exPictureBox)exImages[indexOfImage - 1];
picSelected = px;
px.BorderStyle = BorderStyle.Fixed3D;
px = (exPictureBox)exImages[indexOfImage];
px.BorderStyle = BorderStyle.FixedSingle;
}
}
if (e.Button == toolBar.Buttons[3])
{
if (indexOfImage != (exImages.Count))
{
px = (exPictureBox)exImages[exImages.Count - 1];
px.BorderStyle = BorderStyle.Fixed3D;
if (indexOfImage >= 1)
{
px = (exPictureBox)exImages[indexOfImage - 1];
picSelected = px;
px.BorderStyle = BorderStyle.FixedSingle;
}
indexOfImage = exImages.Count;
}
}
if (e.Button == toolBar.Buttons[2])
{
px = (exPictureBox)exImages[0];
px.BorderStyle = BorderStyle.Fixed3D;
if (indexOfImage > 1)
{
px = (exPictureBox)exImages[indexOfImage - 1];
picSelected = px;
px.BorderStyle = BorderStyle.FixedSingle;
}
indexOfImage = 1;
}
}
}
Testing the Control
1. Open a new instance of the VS .NET. Create a new project choosing the Windows Application template.
2. From a new Windows Forms project, we can add the compiled custom control to the toolbox. You can choose menu Tools then Choose Toolbox Items.., and from the .NET Framework Components tab, clicking Browse and locating the Control Library DLL # (in our case path is C:\Documents and Settings\GalkinA\My Documents\Visual Studio 2005\Projects\PicDB\PicDB\bin\Debug). The component PicDB will then appear in the Toolbox.
3. For creation table with image field you can use article "Storing and Retrieving Images from SQL Server using Microsoft .NET" or "Load/Unload images into/from DB table"
4. After setting BindingSource and configuration add PicDB component. You can play a bit changing its properties (IconHeight, IconWidth, Dimension, Spacing,
PicTitleFieldName).
Good Luck in building own controls.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.