Tag:开源控件 , 源码下载 , 控件开发 , 控件美化 , 窗体换肤 , Skin , QQ表情 , Windows API , GDI+编程 , SQLite , Socket , 控件透明 , 下拉控件 , HTML 解析器 , 图片水印 , ScrollBar(滚动条) , Google Sitemap , 数据库 , SQL , WinForm , P/Invoke , WinForm控件美化扩展 , ListBox控件

 
您的位置: >> 首页 >> C# 视角 >> C# WinForm控件美化扩展系列之ListBox(续)-显示图标项

C# WinForm控件美化扩展系列之ListBox(续)-显示图标项

2009-11-17  来自:CS 程序员之窗  字体大小:【  
  • 摘要:本文介绍怎样对.NET自带的ListBox控件进行重绘美化,实现一个可以隔行显示不同背景色,每个项显示图标和可以更换边框颜色的ListBoxEx控件。

WinForm程序开发中,ListBox控件是比较常用的一个控件,有时候我们需要一个比较美观的ListBox控件,让用户看ListBox控件显示的信息时比较清晰、形象,我们可以让ListBox控件隔行显示不同的背景色,让每个项显示图标,本文将介绍怎样实现这样的一个ListBox扩展控件。

 

先来看看最终实现ListBox扩展控件的效果图:

 

下面我们一步步的来实现这个ListBox扩展控件。首先,我们来明确一下需要完成的功能:

 

1、  实现ListBox的项隔行显示不同的背景色。

2、  扩展ListBox的项,让它可以显示图标。

3、  实现可以更换ListBox边框的颜色。

 

第一项功能在以前我写的一篇文章《C# WinForm控件美化扩展系列之ListBox中已经介绍过,这里就不介绍了,我们重点介绍后两个功能的实现。

 

要让ListBox的每个项显示图标,首先我们需要定义一个我们自己的ListBoxExItem类对象来代替原来的ListBox项,ListBoxExItem需要包含三个属性:Image,我们的图标;Text,显示的文本;Tag,项的用户自定义数据。下面看看这个对象的代码:

[Serializable]
[TypeConverter(
typeof(ExpandableObjectConverter))]
public class ListBoxExItem : IDisposable
{
Fields

Constructors

Properties

Override Methods

IDisposable 成员
}
 

实现了ListBoxExItem类对象,我们还需要实现一个ListBoxExItemCollection集合,这个集合需要实现IListICollectionIEnumerable接口,用来存储ListBoxExItem对象,像ListBox自己实现的ListBox.ObjectCollection集合那样,我们需要实现一些添加项、删除项等等的一些方法,看看这个集合类的视图和代码:

 


 

ListBoxExItemCollection 类视图 
 

ListBoxExItemCollection 类源码:

[ListBindable(false)]
public class ListBoxExItemCollection
: IList,ICollection,IEnumerable
{
Fields

Constructors

Properties

Public Methods

IList 成员

ICollection 成员

IEnumerable 成员
}

 

准备工作做好了,现在我们来动一动ListBox了,先给它加一个OldItems属性,表示的是它原来的Items属性,然后我们需要用我们自己定义的ListBoxExItemCollection集合来定义一个Items属性,覆盖原来的Items属性,这样在设计的时候就是设计我们自己定义的ListBoxExItem项了,我们就可以设置我们自己的项的图标和文本了。看看这两个属性的定义:

internal ListBox.ObjectCollection OldItems
{
get { return base.Items; }
}

[Localizable(true)]
[MergableProperty(
false)]
[DesignerSerializationVisibility(
DesignerSerializationVisibility.Content)]
public new ListBoxExItemCollection Items
{
get { return _items; }
}

 

最后就是DrawItem了,我们直接用我们自己自定义的Items就可以获取需要绘制的ListBoxExItem项了,我们把图标和文本绘好就OK了。看看绘制的代码:

protected override void OnDrawItem(DrawItemEventArgs e)
{
base.OnDrawItem(e);

if (e.Index != -1 && base.Items.Count > 0)
{
System.Diagnostics.Debug.WriteLine(e.State);
Rectangle bounds
= e.Bounds;
ListBoxExItem item
= Items[e.Index];
Graphics g
= e.Graphics;

if ((e.State & DrawItemState.Selected)
== DrawItemState.Selected)
{
RenderBackgroundInternal(
g,
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, bounds);
}

}


Image image
= item.Image;

Rectangle imageRect
= new Rectangle(
bounds.X
+ 2,
bounds.Y
+ 2,
bounds.Height
- 4,
bounds.Height
- 4);
Rectangle textRect
= new Rectangle(
imageRect.Right
+ 2,
bounds.Y,
bounds.Width
- imageRect.Right - 2,
bounds.Height);

string text = item.ToString();
TextFormatFlags formatFlags
=
TextFormatFlags.VerticalCenter;
if (RightToLeft == RightToLeft.Yes)
{
imageRect.X
= bounds.Right - imageRect.Right;
textRect.X
= bounds.Right - textRect.Right;
formatFlags
|= TextFormatFlags.RightToLeft;
formatFlags
|= TextFormatFlags.Right;
}

else
{
formatFlags
|= TextFormatFlags.Left;
}


if (image != null)
{
g.InterpolationMode
=
InterpolationMode.HighQualityBilinear;
g.DrawImage(
image,
imageRect,
0,
0,
image.Width,
image.Height,
GraphicsUnit.Pixel);
}


TextRenderer.DrawText(
g,
text,
Font,
textRect,
ForeColor,
formatFlags);

if ((e.State & DrawItemState.Focus) ==
DrawItemState.Focus)
{
e.DrawFocusRectangle();
}

}

}

 

接下来开始换ListBox控件的边框颜色,这个功能需要用到一些API函数,简单的介绍一下实现的原理,首先我们需要获取ListBox控件非客户区的区域,这个需要注意的地方是需要排除滚动条的区域,应为这个区域系统会自己绘制滚动条的,我们不需要处理。获取非客户区域后,我们就用ListBox控件的背景色来填充它,然后再绘制边框,这些绘制需要在WM_NCPAINT消息中绘制,具体的实现大家可以下载源码看,由于涉及的源码比较多,这里就不贴源码了。

 

好了,现在整个ListBox控件的扩展和美化就完成了,希望你能喜欢,也希望对你有所帮助。最后希望大家继续支持CS程序员之窗。

 

声明:

本文版权归作者和CS 程序员之窗所有,欢迎转载,转载必须保留以下版权信息,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

作者:Starts_2000

出处:CS 程序员之窗 http://www.csharpwin.com

你可以免费使用或修改提供的源代码,但请保留源代码中的版权信息,详情请查看:

CS程序员之窗开源协议 http://www.csharpwin.com/csol.html