自定义组合框(ComboBox)

.net 自带的组合框有点丑

效果图:

可以自定义组合中条目的高度,背景颜色。。。






话不多说,代码如下:

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.ComponentModel;        //指定属性 (Property) 或事件的说明。
using System.Drawing.Drawing2D;


namespace CustomControl
{
    /// <summary>
    /// 自定义 组合框
    /// bds 2012
    /// </summary>
    public class bdsComboBox : ComboBox
    {
        #region private members
        //下拉列表选择项的背景颜色样式
        private ListItemBackColorStyle fSelectedListItemBackColorStyle = ListItemBackColorStyle.Gradient;

        //当下拉列表选择项的背景颜色样式为"渐变"方式时的渐变开始颜色
        private Color fSelectedListItemStartBackColor = Color.FromArgb(255, 251, 237);

        //当下拉列表选择项的背景颜色样式为"渐变"方式时的渐变结束颜色
        private Color fSelectedListItemEndBackColor = Color.FromArgb(255, 236, 181);

        //当下拉列表选择项的背景颜色样式为"正常"方式时背景颜色
        private Color fSelectedListItemBackColor = Color.LightGreen;

        //下拉列表选择项的前景颜色
        private Color fSelectedListItemForeColor = Color.Black;

        //下拉列表选择项的边框颜色
        private Color fSelectedListItemEdgeColor = Color.FromArgb(242, 212, 75);

        //下拉列表项的高度
        private int fListItemHeight = 21;

        //当下拉列表选择项的背景颜色样式为"渐变"方式时,渐变颜色的角度
        private int fSelectedListItemGradientAngle = 90;

        //下拉列表项的文本相对该项顶部坐标的偏移量
        private int fListItemTextOffset = 4;


        private void InitializeComponent()
        {
            this.SuspendLayout();
            this.ResumeLayout(false);
        }
        #endregion

        #region public members
        #region properties
        /// <summary>
        /// 下拉列表项的背景颜色样式
        /// </summary>
        public enum ListItemBackColorStyle
        {
            /// <summary>
            /// 正常模式(单色)
            /// </summary>
            Normal,
            /// <summary>
            /// 渐变颜色
            /// </summary>
            Gradient
        }


        /// <summary>
        /// 下拉列表选择项的背景颜色样式
        /// </summary>
        [Description("下拉列表选择项的背景颜色样式")]
        //[DefaultValue(typeof(bdsComboBox.DropDownListItemBackColorStyle), "Gradient")]
        public ListItemBackColorStyle bdsSelectedListItemBackColorStyle
        {
            set { this.fSelectedListItemBackColorStyle = value; }
            get { return this.fSelectedListItemBackColorStyle; }
        }

        /// <summary>
        /// 当下拉列表选择项的背景颜色样式为"渐变"方式时的渐变开始颜色
        /// </summary>
        [Description("当下拉列表选择项的背景颜色样式为[渐变]方式时的渐变开始颜色")]
        public Color bdsSelectedListItemStartBackColor
        {
            set { this.fSelectedListItemStartBackColor = value; }
            get { return this.fSelectedListItemStartBackColor; }
        }

        /// <summary>
        /// 当下拉列表选择项的背景颜色样式为"渐变"方式时的渐变结束颜色
        /// </summary>
        [Description("当下拉列表选择项的背景颜色样式为[渐变]方式时的渐变结束颜色")]
        public Color bdsSelectedListItemEndBackColor
        {
            set { this.fSelectedListItemEndBackColor = value; }
            get { return this.fSelectedListItemEndBackColor; }
        }

        /// <summary>
        /// 当下拉列表选择项的背景颜色样式为"正常"方式时背景颜色
        /// </summary>
        [Description("当下拉列表选择项的背景颜色样式为[正常]方式时背景颜色")]
        public Color bdsSelectedListItemBackColor
        {
            set { this.fSelectedListItemBackColor = value; }
            get { return this.fSelectedListItemBackColor; }
        }

        /// <summary>
        /// 下拉列表选择项的前景颜色
        /// </summary>
        [Description("下拉列表选择项的前景颜色")]
        public Color bdsSelectedListItemForeColor
        {
            set { this.fSelectedListItemForeColor = value; }
            get { return this.fSelectedListItemForeColor; }
        }

        /// <summary>
        /// 下拉列表选择项的边框颜色
        /// </summary>
        [Description("下拉列表选择项的边框颜色")]
        public Color bdsSelectedListItemEdgeColor
        {
            set { this.fSelectedListItemEdgeColor = value; }
            get { return this.fSelectedListItemEdgeColor; }
        }

        /// <summary>
        /// 下拉列表项的高度
        /// </summary>
        [Description("下拉列表项的高度")]
        public int bdsListItemHeight
        {
            set
            {
                if (value <= 0)
                {
                    throw new Exception("ListItemHeight can't less than 1");
                }
                else
                {
                    this.DropDownHeight = value * this.MaxDropDownItems;
                    this.fListItemHeight = value;
                }
            }
            get { return this.fListItemHeight; }
        }

        /// <summary>
        /// 当下拉列表选择项的背景颜色样式为"渐变"方式时背景颜色渐变的角度
        /// 默认为90度,即垂直方式渐变
        /// </summary>
        [Description("当下拉列表选择项的背景颜色样式为[渐变]方式时背景颜色渐变的角度")]
        public int bdsSelectedListItemGradientAngle
        {
            set { this.fSelectedListItemGradientAngle = value; }
            get { return this.fSelectedListItemGradientAngle; }
        }

        /// <summary>
        /// 下拉列表项文本相对该项顶部坐标的偏移量
        /// 默认为3个像素
        /// </summary>
        [Description("下拉列表项文本相对该项顶部坐标的偏移量")]
        public int bdsListItemTextOffset
        {
            set { this.fListItemTextOffset = value; }
            get { return this.fListItemTextOffset; }
        }
        #endregion

        /// <summary>
        /// 构造函数
        /// </summary>
        public bdsComboBox()
            : base()
        {
            this.SetStyle(ControlStyles.ResizeRedraw |
                     ControlStyles.DoubleBuffer, true);
            this.SetStyle(ControlStyles.Opaque, false);

            this.DrawMode = DrawMode.OwnerDrawVariable;
            this.AutoCompleteMode = AutoCompleteMode.Append
                                    | AutoCompleteMode.Suggest;
            this.AutoCompleteSource = AutoCompleteSource.ListItems;
        }

        /// <summary>
        /// 自定义绘制下拉列表项
        /// </summary>
        /// <param name="e"></param>
        protected override void OnDrawItem(DrawItemEventArgs e)
        {
            base.OnDrawItem(e);
            if (e.Index <= -1)
                return;
            float x = e.Bounds.X;           //X坐标
            float y = e.Bounds.Y;           //Y坐标
            float height = e.Bounds.Height; //高
            float width = e.Bounds.Width;   //宽
            float radius = 1;               //圆角半径
            Brush foreBrush = null;         //前景色画笔
            int dropDownListItemTextOffSet = this.bdsListItemTextOffset;


            if ((e.State & DrawItemState.Selected) != 0)
            {
                //根据下拉列表选择项背景颜色样式的不同,进行绘制
                switch (this.bdsSelectedListItemBackColorStyle)
                {
                    case ListItemBackColorStyle.Gradient:       //渐变方式
                        Brush gradientBrush = new LinearGradientBrush(e.Bounds
                                                                    , this.bdsSelectedListItemStartBackColor
                                                                    , this.bdsSelectedListItemEndBackColor
                                                                    , this.bdsSelectedListItemGradientAngle);
                        Common.FillRoundRectangle(e.Graphics, gradientBrush, x, y, width, height, radius);
                        Common.DrawRoundRectangle(e.Graphics, new Pen(this.bdsSelectedListItemEdgeColor), x, y, width, height - 1, radius);
                        break;
                    case ListItemBackColorStyle.Normal:         //正常方式
                        Brush normalBrush = new SolidBrush(this.bdsSelectedListItemBackColor);
                        Common.FillRoundRectangle(e.Graphics, normalBrush, x, y, width, height, radius);
                        Common.DrawRoundRectangle(e.Graphics, new Pen(this.bdsSelectedListItemEdgeColor), x, y, width, height - 1, radius);
                        break;
                    default:
                        break;
                }

                foreBrush = new SolidBrush(this.bdsSelectedListItemForeColor);
            }
            else
            {
                Brush backBrush = new SolidBrush(this.BackColor);
                e.Graphics.FillRectangle(backBrush, e.Bounds);
                foreBrush = new SolidBrush(this.ForeColor);
                dropDownListItemTextOffSet = this.bdsListItemTextOffset;
            }

            //根据当前字体及文本测试其大小
            //SizeF txtFSize = e.Graphics.MeasureString(this.Items[e.Index].ToString(), this.Font, new SizeF(this.Width, this.bdsListItemHeight));
            //Size txtISize = Size.Ceiling(txtFSize);            

            //绘制项的文本内容
            StringFormat strFormat = new StringFormat();        //设置文本输出格式
            strFormat.FormatFlags = strFormat.FormatFlags | StringFormatFlags.LineLimit | StringFormatFlags.NoWrap;
            strFormat.LineAlignment = StringAlignment.Center;

            string strText = "";
            //strText = this.Items[e.Index].ToString();
            strText = this.GetItemText(this.Items[e.Index]);

            e.Graphics.DrawString(strText, this.Font, foreBrush
                            , new RectangleF(x, y + dropDownListItemTextOffSet, width, height), strFormat);

            e.DrawFocusRectangle();            
        }

        protected override void OnMeasureItem(MeasureItemEventArgs e)
        {
            base.OnMeasureItem(e);
            e.ItemHeight = this.bdsListItemHeight;
        }
        #endregion
    }


    /// <summary>
    /// 共用的一个方法或属性
    /// </summary>
    class Common
    {        
        /// <summary>
        /// 画圆角矩形
        /// </summary>
        /// <param name="g">绘制设备</param>
        /// <param name="p">钢笔</param>
        /// <param name="X">X值</param>
        /// <param name="Y">Y值</param>
        /// <param name="width">宽</param>
        /// <param name="height">高</param>
        /// <param name="radius">圆角半径</param>
        public static void DrawRoundRectangle(Graphics g, Pen p, float X, float Y, float width, float height, float radius)
        {
            try
            {
                System.Drawing.Drawing2D.GraphicsPath path = new System.Drawing.Drawing2D.GraphicsPath();

                path.AddLine(X + radius, Y, X + width - (radius * 2), Y);

                path.AddArc(X + width - (radius * 2), Y, radius * 2, radius * 2, 270, 90);

                path.AddLine(X + width, Y + radius, X + width, Y + height - (radius * 2));

                path.AddArc(X + width - (radius * 2), Y + height - (radius * 2), radius * 2, radius * 2, 0, 90);

                path.AddLine(X + width - (radius * 2), Y + height, X + radius, Y + height);

                path.AddArc(X, Y + height - (radius * 2), radius * 2, radius * 2, 90, 90);

                path.AddLine(X, Y + height - (radius * 2), X, Y + radius);

                path.AddArc(X, Y, radius * 2, radius * 2, 180, 90);

                path.CloseFigure();
                g.DrawPath(p, path);
                path.Dispose();
            }
            catch (Exception ex)
            {
                ;
            }
            finally
            {
            }
        }


        /// <summary>
        /// 填充圆角矩形
        /// </summary>
        /// <param name="g">绘制设备</param>
        /// <param name="b">画笔</param>
        /// <param name="X">X值</param>
        /// <param name="Y">Y值</param>
        /// <param name="width">宽</param>
        /// <param name="height">高</param>
        /// <param name="radius">圆角半径</param>
        public static void FillRoundRectangle(Graphics g, Brush b, float X, float Y, float width, float height, float radius)
        {
            try
            {
                System.Drawing.Drawing2D.GraphicsPath path = new System.Drawing.Drawing2D.GraphicsPath();

                path.AddLine(X + radius, Y, X + width - (radius * 2), Y);

                path.AddArc(X + width - (radius * 2), Y, radius * 2, radius * 2, 270, 90);

                path.AddLine(X + width, Y + radius, X + width, Y + height - (radius * 2));

                path.AddArc(X + width - (radius * 2), Y + height - (radius * 2), radius * 2, radius * 2, 0, 90);

                path.AddLine(X + width - (radius * 2), Y + height, X + radius, Y + height);

                path.AddArc(X, Y + height - (radius * 2), radius * 2, radius * 2, 90, 90);

                path.AddLine(X, Y + height - (radius * 2), X, Y + radius);

                path.AddArc(X, Y, radius * 2, radius * 2, 180, 90);

                path.CloseFigure();

                g.FillPath(b, path);
                path.Dispose();
            }
            catch (Exception ex)
            {
                ;
            }
            finally
            {
            }
        }
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值