这是创建用于从数据库获取图形数据的自定义控件的示例。






2.32/5 (9投票s)
2007 年 3 月 23 日
3分钟阅读

40476

830
这是创建用于从数据库获取图形数据的自定义控件的示例。我将创建一个控件,然后在 Windows 应用程序中测试我的控件。我已经为我的控件开发了一些自定义属性。
这是创建用于从数据库获取图形数据的自定义控件的示例。
引言
这是创建用于从数据库获取图形数据的自定义控件的示例。我将创建一个控件,然后在 Windows 应用程序中测试我的控件。我已经为我的控件开发了一些自定义属性。
在标准组件栏中,我们没有像图库那样的组件来从数据库获取图形数据。但是我们可以使用一些标准组件来创建自己的组件。
这是一个简单的 C# 控件,用于从数据库获取图像。
第一次开始使用 .NET 时,我发现标准组件面板中没有一个控件可以像图库一样显示数据库中的图像,于是我决定创建自己的控件……
(使用材料NET 2.0 Windows Forms and Custom Controls in C#,作者:Matthew MacDonald)
使用代码
该项目被设计为一个自定义控件。在文章“带缩放和滚动功能的 PictureBox”中,描述了如何安装和使用此类控件,或者可以查看 CodeProject 上有关该主题的不同文章,例如 Alexandr Khilov 的文章“编写你的自定义控件:一步步”。
方法 / 属性
该控件提供了七个与设计器相关的属性
DataSource
:数据库的数据源。PicFieldName
:图像的数据字段。PicTitleFieldName
:图像标题的数据字段。Dimension
:列之间的间距。IconHeight
:图标的高度IconWidth
:图标的宽度Spacing
:
行之间的间距。
事件
该类有一个 onDoubleClick 事件。如果鼠标左键双击,将触发该事件并显示全尺寸图像。
助手类
类 exPictureBox 是 PictureBox 的扩展,用于保存图像的某些属性。
类 PictureSelectedEventArgs 派生自 System.EventArgs
。我用它来处理图像属性的选择事件。类 PictureDoubleClickEventArgs 派生自 System.
EventArgs
,用于处理图像属性的双击事件。
类 PicFieldConverter 派生自 System.ComponentModel.StringConverter
。我用它来转换属性。
类 PicNameFieldConverter 派生自 System.ComponentModel.StringConverter
,用于转换属性。
类 NamedImage 是一个简单的类,用于保存图像的名称属性。
在代码中,你可以看到如何使用这些类。
构建控件
1. 打开 Visual Studio 并创建一个新项目。你的项目必须基于 **Windows 控件库**模板。将你的项目命名为 PicDB ,然后单击“确定”。
2. 打开项目后,从项目中删除 UserControl 。
3. 现在转到“项目”菜单:**项目 -> 添加用户控件...**,然后在其中选择 **自定义控件**模板。在这种情况下,我们需要“自定义控件”。将其命名为 PicDB
,然后单击“确定”。一个新的自定义控件已添加到你的项目中。
4. 我们首先要做的是更改 PicDB
的基类
覆盖以下行
public partial class PicDB : UserControl
为此行:
public class PicDB : UserControl
为我们的控件添加属性(在准备我们的控件图标之前,并将其命名为 _PicDB.bmp)
[ToolboxBitmap(typeof(PicDB), "_PicDB.bmp")]
5. 设置必要的命名空间。
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. 现在为我们的控件创建一些自定义属性和辅助类。这可以通过将以下代码插入到 PicDB 类内部来完成
private IContainer components; // Each picture box will be a square of dimension X dimension pixels. private int dimension; // The space between the images and the top, left, and right sides. private int border = 5; private int indexOfImage = 0; // The space between each image. private int spacing; private Panel pnlPictures; // The images that were found in the selected table. 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; //Click on pictures private void onPicClick(object sender, EventArgs e) { // Clear the border style from the last selected picture box. if (sender != picSelected) { if (picSelected != null) { picSelected.BorderStyle = BorderStyle.FixedSingle; } } // Get the new selection. picSelected = (exPictureBox)sender; picSelected.BorderStyle = BorderStyle.Fixed3D; // Fire the selection event. PictureSelectedEventArgs args = new PictureSelectedEventArgs(picSelected.Tag.ToString(), picSelected.Image); indexOfImage = System.Convert.ToInt32(picSelected.Tag) + 1; if (PictureSelected != null) { PictureSelected(this, args); } OnClick(args); } //Double click on pictures private void onDoubleClick(object sender, EventArgs e) { if (picSelected.Image != null) { Form ModalForm = new Form(); PictureBox PicImg = new PictureBox(); //Load Image 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(); } } //Fields array lists static ArrayList _PicField = new ArrayList(); static ArrayList _PicNameField = new ArrayList(); //Dimension amoung Images [Description("Height of Images."), DefaultValue(120), Category("Images")] public int IconHeight { get { return iconHeight; } set { iconHeight = value; } } //Dimension amoung Images [Browsable(true), Description("Width of Images."), DefaultValue(80), Category("Images")] public int IconWidth { get { return iconWidth; } set { iconWidth = value; } } //Dimension amoung Images [Browsable(true)] [DefaultValue(100)] [Category("Images")] [Description("Dimension amoung Images.")] public int Dimension { get { return dimension; } set { dimension = value; } } //Spacing amoung Images [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) { //Separate fields name _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) { //true means show a combobox return true; } public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) { //true will limit to list. false will show the list, but allow free-form entry return true; } public override System.ComponentModel.TypeConverter.StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) { return new StandardValuesCollection(_PicField); } } //Property converter public class PicNameFieldConverter : StringConverter { public override bool GetStandardValuesSupported(ITypeDescriptorContext context) { //true means show a combobox return true; } public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) { //true will limit to list. false will show the list, but allow free-form entry 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")] //Field name property public string PicFieldName { //When first loaded set property with the first item in the rule list. 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")] //Title name property public string PicTitleFieldName { //When first loaded set property with the first item in the rule list. get { string S = ""; if (FieldNameTitle != null) { if (this.DataSet != null) S = FieldNameTitle; else S = ""; } return S; } set { FieldNameTitle = value; } } //Get data sourse [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; } } //Get all images from Data Base 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(); } // Update the display on the UI thread. pnlPictures.Invoke(new MethodInvoker(this.UpdateDisplay)); } private void GetImages() { Thread getThread = new Thread(new ThreadStart(this.GetImagesDB)); getThread.Start(); } //Draw images private void UpdateDisplay() { // Clear the current display. // Suspend layout to prevent multiple window refreshes. if ((IconWidth != 0) && (IconHeight != 0)) { pnlPictures.SuspendLayout(); // Clear the current display. foreach (Control ctrl in pnlPictures.Controls) { ctrl.Dispose(); } pnlPictures.Controls.Clear(); // Row and Col will track the current position where pictures are // being inserted. They begin at the top-left corner. int row = border, col = border; int imgW, imgH = 0; double reSize, reSize1 = 0; //Rectangle destRect = new Rectangle(); int i = 0; // Iterate through the Images collection, and create PictureBox controls. 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); // Display the picture. pnlPictures.Controls.Add(pic); // Move to the next column. col += (int)Math.Ceiling((double)((dimension + IconHeight* IconWidth / IconHeight)); // Move to next line if no more pictures will fit. 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; //Mouse scroll 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 /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> 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(); // // pnlPictures // 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; // // pnToolBar // 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; // // toolBar // 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); // // tbntNext // this.tbntNext.ImageIndex = 0; this.tbntNext.Name = "tbntNext"; // // tbntPrior // this.tbntPrior.ImageIndex = 1; this.tbntPrior.Name = "tbntPrior"; // // tbntLast // this.tbntLast.ImageIndex = 2; this.tbntLast.Name = "tbntLast"; // // tbntFirst // this.tbntFirst.ImageIndex = 3; this.tbntFirst.Name = "tbntFirst"; // // imgList // 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"); // // openFileDialog // this.openFileDialog.Filter = "Image Files | *.JPG;*.GIF;*.BMP"; // // PicDB // 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); } //Processing toolbar button private void toolBar_ButtonClick(object sender, ToolBarButtonClickEventArgs e) { exPictureBox px = new exPictureBox(); //next action 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++; } //prior action 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; } } //last position 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; } } //first position 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; } } }
测试控件
1. 打开 VS .NET 的新实例。创建选择 **Windows 应用程序**模板的新项目。
2. 从新的 Windows Forms 项目中,我们可以将编译后的自定义控件添加到工具箱。你可以选择菜单 **工具**,然后 **选择** **工具箱项..**,然后在 **.NET Framework 组件**选项卡中,单击 **浏览**并找到控件库 DLL #(在本例中,路径是C:\Documents and Settings\GalkinA\My Documents\Visual Studio 2005\Projects\PicDB\PicDB\bin\Debug)。然后,组件 **PicDB** 将出现在工具箱中。
3. 要创建带有图像字段的表,你可以使用文章““使用 Microsoft .NET 将图像存储和检索到 SQL Server””或““加载/卸载图像到/从 DB 表””
4. 设置 BindingSource 和配置后,添加 **PicDB** 组件。你可以尝试更改其属性(IconHeight,IconWidth,Dimension,Spacing,
PicTitleFieldName)。
祝你在构建自己的控件方面好运。