C# 编写带图标和tooltip的ListBox[续]--Item背景色交替变化
来源:互联网 发布:产品介绍网站源码 编辑:程序博客网 时间:2024/04/30 06:11
跟随前文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); } }
- C# 编写带图标和tooltip的ListBox[续]--Item背景色交替变化
- C# 编写带图标和tooltip的ListBox
- C# 编写带图标和tooltip的ListBox
- C# ListBox奇偶行 交替背景色
- C# 编写带ToolTip的ListBox
- C# 编写带ToolTip的ListBox
- QT控制选中item的文字颜色(HighlightedText) 和 QT表格交替背景色
- QT控制选中item的文字颜色(HighlightedText) 和 QT表格交替背景色
- uitable的交替背景色
- Listview的item选中时的背景色的变化
- GridView的Item选中后,背景色会有变化,如何才能去除这个背景色呢,
- Axure交替背景色
- QTableWidget背景色交替
- win8中ListView、GridView、ListBox如何更改Item的背景色、间距之类等?
- win8中ListView、GridView、ListBox如何更改Item的背景色、间距之类等? .
- Android_Button背景色的变化
- 带图标和自定义颜色的ListBox
- 带图标和自定义颜色的ListBox
- 如果忘记windows密码,该怎么办?
- 新的一年
- <<C++程序设计原理与实践>>粗读 -- chapter6 Chapter7
- 复习一下MSIL的一些问题
- js不能提交表单,提示对象支持此属性和方法
- C# 编写带图标和tooltip的ListBox[续]--Item背景色交替变化
- boost::function学习
- c++编程修养
- 运用加密技术保护Java源代码 (转)
- 无题(2012.1.8)
- C++笔试题——华为
- c/c++笔试题大解析
- stl map 总结
- java实现邮件的发送包括网页文件的发送