.Net自带的ComboBox功能比较局限,例如:不能显示图标,不能禁用滚轮等,本文将通过继承.Net原有的ComboBox设计一个功能更完善的ComboBoxEx
声明:
本文的代码来自CodeProject,并加以修改,原文连接:
http://www.codeproject.com/cs/combobox/ImageCombo_NET.asp
相比原有的ComboBox,ComboBoxEx具有以下新功能:
1.可以显示图标;
2.可以禁用滚轮;
3.可以设置在文本框中显示的文本;
4.可以设置缩进.
设计要点:
1.重写OnDrawItem方法,用this.ImageList.Draw绘制图标;
2.重写窗体消息函数WndProc,屏蔽WM_MOUSEWHEEL(=0x020A)事件;
3.重写ToString方法.
下面将给出ComboBoxEx的详细设计:
1.定义储存ComboBoxEx项数据的类:
public partial class FolderBrowser : UserControl { #region 共有方法和属性说明 [Browsable(true), Description("设置或获取根节点路径"), Category("外观")] public string RootPath; [Browsable(true), Description("设置或获取当前选中的文件夹的路径"), Category("外观")] public string SelectedPath; [Browsable(true), Description("设置或获取根路径的名称(即根节点的文本)"), Category("外观")] public string RootText; [Browsable(true), Description("设置或获取是否显示隐藏文件夹"), Category("行为")] public bool ShowHiddenDir; #endregion #region 若要实现FolderBrowser功能,重写以下虚函数(重写时不需调用基类函数) //返回指定目录的所有子目录,并通过Dirs返回(用于左侧目录树) //重写说明: //(1)必须重写该方法 //(2)当获取子目录和文件失败时,必须抛出异常GetSubDirsException //参数: //(1)path[in]:要获取目录信息的目录路径; //(2)filter[in]:筛选字符串 //(3)Dirs[out]:用于返回所有子目录 virtual protected void GetSubDirectory(string path, out LDirectoryInfo[] di); /// <summary> ///检索计算机上的所有逻辑驱动器的驱动器名称 ///返回值:返回LDriveInfo数组,表示计算机上的逻辑驱动器。 ///重写说明: ///(1)当根目录为我的电脑时,必须重写该方法 ///(2)当获取逻辑驱动器失败时,必须抛出异常GetDrivesException /// </summary> virtual protected void GetAllDrive(out LDriveInfo[] di); #endregion } using System; using System.Drawing; namespace System.Windows.Forms { public class ComboBoxExItem : object { // forecolor: transparent = inherit private Color forecolor = Color.FromKnownColor(KnownColor.Transparent); //字体颜色 private bool mark = false; private int imageindex = -1; //使用的图标 private object tag = null; //包含有关控件的数据的对象 private string text = null; //项的文本 private int _Retract = 0; //缩进大小 private string _stext; //当该项被选中时在文本框中显示的字符串,默认与该项的文本相同 // 构造函数 public ComboBoxExItem() { } public ComboBoxExItem(string Text) { text = Text; _stext = Text; } public ComboBoxExItem(int retract, string Text) { _Retract = retract; text = Text; _stext = Text; } public ComboBoxExItem(int retract, string Text, int ImageIndex) { _Retract = retract; text = Text; _stext = Text; imageindex = ImageIndex; } public ComboBoxExItem(int retract, string Text, int ImageIndex, object Tag) { _Retract = retract; text = Text; _stext = Text; imageindex = ImageIndex; tag = Tag; } public ComboBoxExItem(int retract, string Text, string stext, int ImageIndex, object Tag) { _Retract = retract; text = Text; _stext = stext; imageindex = ImageIndex; tag = Tag; } public ComboBoxExItem(int retract, string Text, int ImageIndex, bool Mark) { _Retract = retract; text = Text; _stext = Text; imageindex = ImageIndex; mark = Mark; } public ComboBoxExItem(int retract, string Text, int ImageIndex, bool Mark, Color ForeColor) { _Retract = retract; text = Text; _stext = Text; imageindex = ImageIndex; mark = Mark; forecolor = ForeColor; } public ComboBoxExItem(int retract, string Text, int ImageIndex, bool Mark, Color ForeColor, object Tag) { _Retract = retract; text = Text; _stext = Text; imageindex = ImageIndex; mark = Mark; forecolor = ForeColor; tag = Tag; } // 设置或获取字体颜色 public Color ForeColor { get { return forecolor; } set { forecolor = value; } } // 设置或获取该项使用的图标 public int ImageIndex { get { return imageindex; } set { imageindex = value; } } // mark (bold) public bool Mark { get { return mark; } set { mark = value; } } // 设置或获取相关的数据对象 public object Tag { get { return tag; } set { tag = value; } } // 设置或获取该项的文本 public string Text { get { return text; } set { text = value; } } // 设置或获取该项的缩进 public int Retract { get { return _Retract; } set { _Retract = value; } } // 设置或获取显示文本 public string sText { get { return _stext; } set { _stext = value; } } //重写ToString方法 //当该项被选中时,控件将调用该函数获取显示在文本框中的文本 public override string ToString() { return _stext; } } }
2.定义ComboBoxEx:
using System; using System.Drawing; using System.ComponentModel; namespace System.Windows.Forms { public class ComboBoxEx : ComboBox { private ImageList imgs = new ImageList(); //该组合框使用的ImageList private bool _DisableMouseWheel = false; //是否禁用滚轮 // constructor public ComboBoxEx() { // set draw mode to owner draw this.DrawMode = DrawMode.OwnerDrawFixed; } // 设置或获取ImageList public ImageList ImageList { get { return imgs; } set { imgs = value; } } protected override void OnPaint(PaintEventArgs e) { //base.OnPaint(e); } //重写项绘制函数 protected override void OnDrawItem(DrawItemEventArgs e) { // draw background & focus rect e.DrawBackground(); e.DrawFocusRectangle(); // check if it is an item from the Items collection if (e.Index < 0) // not an item, draw the text (indented) e.Graphics.DrawString(this.Text, e.Font, new SolidBrush(e.ForeColor), e.Bounds.Left + imgs.ImageSize.Width, e.Bounds.Top + (e.Bounds.Height - e.Font.Height) / 2); else { // check if item is an ComboBoxExItem if (this.Items[e.Index].GetType() == typeof(ComboBoxExItem)) { // get item to draw ComboBoxExItem item = (ComboBoxExItem)this.Items[e.Index]; // get forecolor & font Color forecolor = (item.ForeColor != Color.FromKnownColor(KnownColor.Transparent)) ? item.ForeColor : e.ForeColor; Font font = item.Mark ? new Font(e.Font, FontStyle.Bold) : e.Font; // -1: no image if (item.ImageIndex != -1) { // draw image, then draw text next to it this.ImageList.Draw(e.Graphics, e.Bounds.Left + item.Retract, e.Bounds.Top, item.ImageIndex); e.Graphics.DrawString(item.Text, font, new SolidBrush(forecolor), e.Bounds.Left + imgs.ImageSize.Width + item.Retract, e.Bounds.Top + (e.Bounds.Height - e.Font.Height) / 2); } else // draw text (indented) e.Graphics.DrawString(item.Text, font, new SolidBrush(forecolor), e.Bounds.Left + imgs.ImageSize.Width + item.Retract, e.Bounds.Top + (e.Bounds.Height - e.Font.Height) / 2); } else // it is not an ComboBoxExItem, draw it e.Graphics.DrawString(this.Items[e.Index].ToString(), e.Font, new SolidBrush(e.ForeColor), e.Bounds.Left + imgs.ImageSize.Width, e.Bounds.Top + (e.Bounds.Height - e.Font.Height) / 2); } base.OnDrawItem(e); } //设置或获取滚轮是否被禁用 [Browsable(true), Description("禁用滚轮"), Category("行为")] public bool DisableMouseWheel { get { return _DisableMouseWheel; } set { _DisableMouseWheel = value; } } //重写消息处理函数 protected override void WndProc(ref Message m) { switch (m.Msg) { case 0x020A: //如要屏蔽滚轮,则直接返回,否则,将消息传给基类的WndProc if (_DisableMouseWheel) return; else break; default: break; } base.WndProc(ref m); } } }