代码改变世界

转:扩展ComboBox(.Net)

2013-03-15 13:43  robinli  阅读(232)  评论(0编辑  收藏  举报

源码下载

.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);
        }
    }
}