绘制出 Office 07 般的美丽 ListBox
做个小东西的时候,需要用到 ListBox,而其中每一个 Item 我都希望更美观、能显示更多信息,所以决定重绘。想起 Office 07如此怎办怎办如此的美轮美奂我也心痒,就说做不到人家那么漂漂,总能弄个差不多吧,说做就做,于是开始行动。我没有 Office 07 (懒得装),就打开微软的 Office 页面,反正上面的风格也差不多,再找了个很好用的屏幕吸取颜色的小工具来拾取不同的颜色搭配。光看表面,也知道 Office 07 的橘色效果不是单纯的渐变,所以拾取颜色是很重要的,看它如何搭配。一切妥当之后,便开始使用 GDI+ 绘制我的 ListBox ...
蓝色的背景我试了一下,不是画不出来,只是想画成 Office 那样的统一的风格实在是很费精力,也没有必要,所以我最终的颜色搭配也没有留下,下面贴出绘制橘色渐变的部分代码吧,里边含有颜色的 RGB 分量和笔刷的定义方式。
以下是 ListBox 绘制时的代码
private void clientListBox_MeasureItem(object sender, MeasureItemEventArgs e)
{
e.ItemWidth = clientListBox.ClientSize.Width-1;
e.ItemHeight = 48;
}
private void clientListBox_DrawItem(object sender, DrawItemEventArgs e)
{
if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)
{
#region 绘制渐变背景
LinearGradientBrush bgBrush = paint.SelectedItemBackgroundBrush(e.Bounds);
e.Graphics.FillRectangle(bgBrush, e.Bounds);
bgBrush.Dispose();
#endregion
#region 绘制底边边框
Pen framePen = paint.SelectedFramePen; //底边边框画笔
//底边边框的四点所连成的矩形
//Point[] framePoints = new Point[] { new Point(e.Bounds.X, e.Bounds.Y),
// new Point(e.Bounds.Width - 1, e.Bounds.Y + 1),
// new Point(e.Bounds.Width - 1, e.Bounds.Y + e.Bounds.Height - 1),
// new Point(e.Bounds.X + 1, e.Bounds.Y + e.Bounds.Height - 1),
// new Point(e.Bounds.X + 1, e.Bounds.Y + 1) };
Point[] framePoints = new Point[] { new Point(e.Bounds.X, e.Bounds.Y),
new Point(e.Bounds.Width-1, e.Bounds.Y),
new Point(e.Bounds.Width-1, e.Bounds.Y + e.Bounds.Height-1),
new Point(e.Bounds.X, e.Bounds.Y + e.Bounds.Height-1),
new Point(e.Bounds.X, e.Bounds.Y) };
//绘制底边边框
e.Graphics.DrawLines(framePen, framePoints);
framePen.Dispose();
#endregion
#region 绘制图标
Rectangle iconRect = new Rectangle(8, e.Bounds.Y + 8, 32, 32);
e.Graphics.DrawIcon(iConnection.Server.Resource.Icon.Host, iconRect);
#endregion
#region 绘制图像
//Rectangle imageRect = new Rectangle(8, e.Bounds.Y + 8, 32, 32);
//e.Graphics.DrawImage(iConnection.Server.Resource.Image.Connected, imageRect);
#endregion
}
else
{
e.DrawBackground();
#region 绘制图标
Rectangle iconRect = new Rectangle(8, e.Bounds.Y + 8, 32, 32);
e.Graphics.DrawIcon(iConnection.Server.Resource.Icon.Host, iconRect);
#endregion
#region 绘制图像
//Rectangle imageRect = new Rectangle(8, e.Bounds.Y + 8, 32, 32);
//e.Graphics.DrawImage(iConnection.Server.Resource.Image.DisConnected, imageRect);
#endregion
}
}
我使用了一个单独的 Paint 类来定义各项笔刷的形式和颜色,以下是橘色笔刷的定义部分
/// <summary>
/// 获取绘制选中项背景的画笔
/// </summary>
/// <param name="r"></param>
/// <returns></returns>
public LinearGradientBrush SelectedItemBackgroundBrush(Rectangle r)
{
Color topColor = Color.FromArgb(255, 236, 195);
Color bottomColor = Color.FromArgb(255, 217, 131);
LinearGradientBrush brush = new LinearGradientBrush(r, topColor, bottomColor, LinearGradientMode.Vertical);
ColorBlend cb = new ColorBlend();
cb.Colors = new Color[] { Color.FromArgb(255, 236, 195), Color.FromArgb(255, 217, 131), Color.FromArgb(255, 191, 48), Color.FromArgb(255, 219, 84) };
cb.Positions = new float[] { 0.0f, 0.39f, 0.4f, 1.0f };
brush.InterpolationColors = cb;
return brush;
}
下面是边框画笔的定义
/// <summary>
/// 返回绘制选中项的边框画笔
/// </summary>
public Pen SelectedFramePen
{
get { return new Pen(Color.FromArgb(191, 162, 119), 1); }
}
代码很简单,通过此方法,可以扩展出更多更好的绘制方法,目前来讲,挺漂亮,偶很满意