C# 编写带图标和tooltip的ListBox[续]--Item背景色交替变化

跟随前文http://blog.csdn.net/luols/article/details/7184155的脚步继续探索,我们对重写的ListBox项背景色加以控制,让其交替变化显示,并对选中项背景色用渐变刷子,当项被选中时,背景色有一个渐变过程,我们先看下最终的效果:

关键代码在前文已有详尽描述,这里只补充三个属性,以及OnDrawItem方法的重写

三个属性(已设置默认值):

        private Color _rowBackColor1 = Color.White;
        private Color _rowBackColor2 = Color.FromArgb(254, 216, 249);
        private Color _selectedColor = Color.FromArgb(102, 206, 255);
        /// <summary>
        /// 选中项背景色
        /// </summary>
        [Description("选中项背景色")]
        public Color SelectedColor
        {
            get { return _selectedColor; }
            set { _selectedColor = value; }
        }
        /// <summary>
        /// 奇数项背景色
        /// </summary>
        [Description("奇数项背景色")]
        public Color RowBackColor1
        {
            get { return _rowBackColor1; }
            set { _rowBackColor1 = value; }
        }
        /// <summary>
        /// 偶数项背景色
        /// </summary>
        [Description("偶数项背景色")]
        public Color RowBackColor2
        {
            get { return _rowBackColor2; }
            set { _rowBackColor2 = value; }
        }


OnDrawItem方法(主要增加了对项背景色的控制)

        protected override void OnDrawItem(DrawItemEventArgs e)
        {
            e.DrawBackground();
            e.DrawFocusRectangle();

            if (e.Index != MyListBox.NoMatches && base.Items.Count > 0)
            {
                Graphics g = e.Graphics;
                StringFormat sf = new StringFormat();
                sf.Trimming = StringTrimming.EllipsisCharacter; //超出指定矩形区域部分用"..."替代
                sf.LineAlignment = StringAlignment.Center;//垂直居中

                MyListBoxItem item = (MyListBoxItem)Items[e.Index];
                if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)
                { //选中项背景色设置
                    RenderHelper.RenderBackgroundInternal(
                        g, e.Bounds, _selectedColor, _selectedColor,
                        Color.FromArgb(200, 255, 255, 255),
                        0.45f, true, LinearGradientMode.Vertical);
                }
                else
                {
                    Color backColor;
                    if (e.Index % 2 == 0) //偶数项
                    {
                        backColor = _rowBackColor2;
                    }
                    else //奇数项
                    {
                        backColor = _rowBackColor1;
                    }
                    using (SolidBrush brush = new SolidBrush(backColor))
                    {
                        g.FillRectangle(brush, e.Bounds);
                    }
                }
                SizeF size = g.MeasureString(item.Text, e.Font); //获取项文本尺寸
                if (HasIcon) //带图标时
                {
                    if (size.Width > e.Bounds.Width - this.IconWidth) //项文本宽度超过 项宽-图标宽度
                    {
                        item.ShowTip = true; //显示tooltip
                    }
                    /* 获取指定矩形区域,注意不能直接用项所在矩形,否则DrawString时会出现自动换行
                     * 的情况。前面说超出指定矩形区域用“...”替代 指的是DrawString方法会先塞满整个
                     * 矩形区域,如果区域高度够时,就会出现自动换行的情况 ******/
                    RectangleF rectF = new RectangleF(e.Bounds.Left,
                        e.Index * this.ItemHeight + (this.ItemHeight - size.Height) / 2.0f,
                        e.Bounds.Width - this.IconWidth, size.Height);

                    //写 项文本
                    g.DrawString(item.Text, e.Font, new SolidBrush(e.ForeColor), rectF, sf);
                    if (item.ItemImage != null) //在项右侧 画图标
                    {
                        g.InterpolationMode = InterpolationMode.HighQualityBilinear;

                        /* 注意不能用DrawImage(img, x, y)方法,务必指定图标的大小,
                         * 否则会导致图标被放大,读者不妨一试 :)  *****/
                        g.DrawImage(item.ItemImage, e.Bounds.Right - this.IconWidth, e.Bounds.Top, this.IconWidth, this.IconHeight);
                    }
                }
                else //不带图标
                {
                    if (size.Width > e.Bounds.Width) //项文本宽度超过 项宽
                    {
                        item.ShowTip = true; //显示tooltip
                    }
                    //获取指定矩形区域
                    RectangleF rectF = new RectangleF(e.Bounds.Left,
                        e.Index * this.ItemHeight + (this.ItemHeight - size.Height) / 2.0f,
                        e.Bounds.Width, size.Height);
                    //写 项文本
                    g.DrawString(item.Text, e.Font, new SolidBrush(e.ForeColor), rectF, sf);
                }
            }
            base.OnDrawItem(e);
        }


这里面有一个RenderHelper类

    class RenderHelper
    {
        public static void RenderBackgroundInternal(Graphics g, Rectangle rect,
            Color baseColor, Color borderColor, Color innerBorderColor,
            float basePosition, bool drawBorder, LinearGradientMode mode)
        {
            if (drawBorder)
            {
                rect.Width--;
                rect.Height--;
            }
            using (LinearGradientBrush brush = new LinearGradientBrush(
                rect, Color.Transparent, Color.Transparent, mode))
            {
                Color[] colors = new Color[4];
                colors[0] = GetColor(baseColor, 0, 35, 24, 9);
                colors[1] = GetColor(baseColor, 0, 13, 8, 3);
                colors[2] = baseColor;
                colors[3] = GetColor(baseColor, 0, 68, 69, 54);

                ColorBlend blend = new ColorBlend();
                blend.Positions = new float[] { 0.0f, basePosition, basePosition + 0.05f, 1.0f };
                blend.Colors = colors;
                brush.InterpolationColors = blend;
                g.FillRectangle(brush, rect);
            }
            if (baseColor.A > 80)
            {
                Rectangle rectTop = rect;
                if (mode == LinearGradientMode.Vertical)
                {
                    rectTop.Height = (int)(rectTop.Height * basePosition);
                }
                else
                {
                    rectTop.Width = (int)(rect.Width * basePosition);
                }
                using (SolidBrush brushAlpha =
                    new SolidBrush(Color.FromArgb(80, 255, 255, 255)))
                {
                    g.FillRectangle(brushAlpha, rectTop);
                }
            }
            if (drawBorder)
            {
                using (Pen pen = new Pen(borderColor))
                {
                    g.DrawRectangle(pen, rect);
                }

                rect.Inflate(-1, -1);
                using (Pen pen = new Pen(innerBorderColor))
                {
                    g.DrawRectangle(pen, rect);
                }
            }
        }

        private static Color GetColor(Color colorBase, int a, int r, int g, int b)
        {
            int a0 = colorBase.A;
            int r0 = colorBase.R;
            int g0 = colorBase.G;
            int b0 = colorBase.B;

            if (a + a0 > 255) { a = 255; } else { a = Math.Max(a + a0, 0); }
            if (r + r0 > 255) { r = 255; } else { r = Math.Max(r + r0, 0); }
            if (g + g0 > 255) { g = 255; } else { g = Math.Max(g + g0, 0); }
            if (b + b0 > 255) { b = 255; } else { b = Math.Max(b + b0, 0); }

            return Color.FromArgb(a, r, g, b);
        }
    }


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值