listbox美化

摘要:
先来看看最终实现ListBox扩展控件的效果图:下面我们一步步的来实现这个ListBox扩展控件。首先,我们来明确一下需要完成的功能:1、实现ListBox的项隔行显示不同的背景色。第一项功能在以前我写的一篇文章《C#WinForm控件美化扩展系列之ListBox》中已经介绍过,这里就不介绍了,我们重点介绍后两个功能的实现。

http://www.csharpwin.com/csharpresource/5261r2896.shtml

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

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

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

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

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

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

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

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

listbox美化第1张[Serializable]
listbox美化第1张 [TypeConverter(
typeof(ExpandableObjectConverter))]
listbox美化第1张
public classListBoxExItem : IDisposable
{
listbox美化第4张listbox美化第5张
FieldsFields
listbox美化第6张
listbox美化第6张
private string_text = "ListBoxExItem";
listbox美化第6张
privateImage _image;
listbox美化第6张
private object_tag;
listbox美化第6张
listbox美化第11张
#endregion

listbox美化第6张
listbox美化第4张listbox美化第5张
ConstructorsConstructors
listbox美化第6张
listbox美化第6张
publicListBoxExItem()
listbox美化第17张listbox美化第18张
{
listbox美化第11张 }

listbox美化第6张
listbox美化第6张
publicListBoxExItem(stringtext)
listbox美化第6张 :
this(text, null)
listbox美化第17张listbox美化第18张
{
listbox美化第11张 }

listbox美化第6张
listbox美化第6张
publicListBoxExItem(stringtext, Image image)
listbox美化第17张listbox美化第18张
{
listbox美化第6张 _text
=text;
listbox美化第6张 _image
=image;
listbox美化第11张 }

listbox美化第6张
listbox美化第11张
#endregion
listbox美化第6张
listbox美化第4张listbox美化第5张
PropertiesProperties
listbox美化第6张
listbox美化第6张 [DefaultValue(
"ImageComboBoxItem")]
listbox美化第6张 [Localizable(
true)]
listbox美化第6张
public stringText
listbox美化第17张listbox美化第18张
{
listbox美化第17张listbox美化第18张
get { return_text; }
listbox美化第17张listbox美化第18张
set { _text =value; }
listbox美化第11张 }

listbox美化第6张
listbox美化第6张 [DefaultValue(
typeof(Image), "null")]
listbox美化第6张
publicImage Image
listbox美化第17张listbox美化第18张
{
listbox美化第17张listbox美化第18张
get { return_image; }
listbox美化第17张listbox美化第18张
set { _image =value; }
listbox美化第11张 }

listbox美化第6张
listbox美化第6张 [Bindable(
true)]
listbox美化第6张 [Localizable(
false)]
listbox美化第6张 [DefaultValue(
"")]
listbox美化第6张 [TypeConverter(
typeof(StringConverter))]
listbox美化第6张 [DesignerSerializationVisibility(
listbox美化第6张 DesignerSerializationVisibility.Hidden)]
listbox美化第6张
public objectTag
listbox美化第17张listbox美化第18张
{
listbox美化第17张listbox美化第18张
get { return_tag; }
listbox美化第17张listbox美化第18张
set { _tag =value; }
listbox美化第11张 }

listbox美化第6张
listbox美化第11张
#endregion
listbox美化第6张
listbox美化第4张listbox美化第5张
Override MethodsOverride Methods
listbox美化第6张
listbox美化第6张
public override stringToString()
listbox美化第17张listbox美化第18张
{
listbox美化第6张
return_text;
listbox美化第11张 }

listbox美化第6张
listbox美化第11张
#endregion
listbox美化第6张
listbox美化第4张listbox美化第5张
IDisposable 成员IDisposable 成员
listbox美化第6张
listbox美化第6张
public voidDispose()
listbox美化第17张listbox美化第18张
{
listbox美化第6张 _image
= null;
listbox美化第6张 _tag
= null;
listbox美化第11张 }

listbox美化第6张
listbox美化第11张
#endregion
listbox美化第99张 }

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


ListBoxExItemCollection 类视图

ListBoxExItemCollection 类源码:

listbox美化第1张[ListBindable(false)]
listbox美化第1张
public classListBoxExItemCollection
listbox美化第1张 : IList,ICollection,IEnumerable
{
listbox美化第4张listbox美化第5张
FieldsFields
listbox美化第6张
listbox美化第6张
privateListBoxEx _owner;
listbox美化第6张
listbox美化第11张
#endregion

listbox美化第6张
listbox美化第4张listbox美化第5张
ConstructorsConstructors
listbox美化第6张
listbox美化第6张
publicListBoxExItemCollection(ListBoxEx owner)
listbox美化第17张listbox美化第18张
{
listbox美化第6张 _owner
=owner;
listbox美化第11张 }

listbox美化第6张
listbox美化第11张
#endregion
listbox美化第6张
listbox美化第4张listbox美化第5张
PropertiesProperties
listbox美化第6张
listbox美化第6张
internalListBoxEx Owner
listbox美化第17张listbox美化第18张
{
listbox美化第17张listbox美化第18张
get { return_owner; }
listbox美化第11张 }

listbox美化第6张
listbox美化第6张
publicListBoxExItem this[intindex]
listbox美化第17张listbox美化第18张
{
listbox美化第17张listbox美化第18张
get { returnOwner.OldItems[index] asListBoxExItem; }
listbox美化第17张listbox美化第18张
set { Owner.OldItems[index] =value; }
listbox美化第11张 }

listbox美化第6张
listbox美化第6张
public intCount
listbox美化第17张listbox美化第18张
{
listbox美化第17张listbox美化第18张
get { returnOwner.OldItems.Count; }
listbox美化第11张 }

listbox美化第6张
listbox美化第6张
public boolIsReadOnly
listbox美化第17张listbox美化第18张
{
listbox美化第17张listbox美化第18张
get { returnOwner.OldItems.IsReadOnly; }
listbox美化第11张 }

listbox美化第6张
listbox美化第11张
#endregion
listbox美化第6张
listbox美化第4张listbox美化第5张
Public MethodsPublic Methods
listbox美化第6张
listbox美化第6张
public intAdd(ListBoxExItem item)
listbox美化第17张listbox美化第18张
{
listbox美化第6张
if(item == null)
listbox美化第17张listbox美化第18张
{
listbox美化第6张
throw newArgumentNullException("item");
listbox美化第11张 }

listbox美化第6张
returnOwner.OldItems.Add(item);
listbox美化第11张 }

listbox美化第6张
listbox美化第6张
public voidAddRange(ListBoxExItemCollection value)
listbox美化第17张listbox美化第18张
{
listbox美化第6张
foreach(ListBoxExItem item invalue)
listbox美化第17张listbox美化第18张
{
listbox美化第6张 Add(item);
listbox美化第11张 }

listbox美化第11张 }

listbox美化第6张
listbox美化第6张
public voidAddRange(ListBoxExItem[] items)
listbox美化第17张listbox美化第18张
{
listbox美化第6张 Owner.OldItems.AddRange(items);
listbox美化第11张 }

listbox美化第6张
listbox美化第6张
public voidClear()
listbox美化第17张listbox美化第18张
{
listbox美化第6张 Owner.OldItems.Clear();
listbox美化第11张 }

listbox美化第6张
listbox美化第6张
public boolContains(ListBoxExItem item)
listbox美化第17张listbox美化第18张
{
listbox美化第6张
returnOwner.OldItems.Contains(item);
listbox美化第11张 }

listbox美化第6张
listbox美化第6张
public voidCopyTo(
listbox美化第6张 ListBoxExItem[] destination,
listbox美化第6张
intarrayIndex)
listbox美化第17张listbox美化第18张
{
listbox美化第6张 Owner.OldItems.CopyTo(destination, arrayIndex);
listbox美化第11张 }

listbox美化第6张
listbox美化第6张
public intIndexOf(ListBoxExItem item)
listbox美化第17张listbox美化第18张
{
listbox美化第6张
returnOwner.OldItems.IndexOf(item);
listbox美化第11张 }

listbox美化第6张
listbox美化第6张
public voidInsert(intindex, ListBoxExItem item)
listbox美化第17张listbox美化第18张
{
listbox美化第6张
if(item == null)
listbox美化第17张listbox美化第18张
{
listbox美化第6张
throw newArgumentNullException("item");
listbox美化第11张 }

listbox美化第6张 Owner.OldItems.Insert(index, item);
listbox美化第11张 }

listbox美化第6张
listbox美化第6张
public voidRemove(ListBoxExItem item)
listbox美化第17张listbox美化第18张
{
listbox美化第6张 Owner.OldItems.Remove(item);
listbox美化第11张 }

listbox美化第6张
listbox美化第6张
public voidRemoveAt(intindex)
listbox美化第17张listbox美化第18张
{
listbox美化第6张 Owner.OldItems.RemoveAt(index);
listbox美化第11张 }

listbox美化第6张
listbox美化第6张
publicIEnumerator GetEnumerator()
listbox美化第17张listbox美化第18张
{
listbox美化第6张
returnOwner.OldItems.GetEnumerator();
listbox美化第11张 }

listbox美化第6张
listbox美化第11张
#endregion
listbox美化第6张
listbox美化第4张listbox美化第5张
IList 成员IList 成员
listbox美化第6张
listbox美化第6张
intIList.Add(objectvalue)
listbox美化第17张listbox美化第18张
{
listbox美化第6张
if(!(value isListBoxExItem))
listbox美化第17张listbox美化第18张
{
listbox美化第6张
throw newArgumentException();
listbox美化第11张 }

listbox美化第6张
returnAdd(value asListBoxExItem);
listbox美化第11张 }

listbox美化第6张
listbox美化第6张
voidIList.Clear()
listbox美化第17张listbox美化第18张
{
listbox美化第6张 Clear();
listbox美化第11张 }

listbox美化第6张
listbox美化第6张
boolIList.Contains(objectvalue)
listbox美化第17张listbox美化第18张
{
listbox美化第6张
returnContains(value asListBoxExItem);
listbox美化第11张 }

listbox美化第6张
listbox美化第6张
intIList.IndexOf(objectvalue)
listbox美化第17张listbox美化第18张
{
listbox美化第6张
returnIndexOf(value asListBoxExItem);
listbox美化第11张 }

listbox美化第6张
listbox美化第6张
voidIList.Insert(intindex, objectvalue)
listbox美化第17张listbox美化第18张
{
listbox美化第6张
if(!(value isListBoxExItem))
listbox美化第17张listbox美化第18张
{
listbox美化第6张
throw newArgumentException();
listbox美化第11张 }

listbox美化第6张 Insert(index, value
asListBoxExItem);
listbox美化第11张 }

listbox美化第6张
listbox美化第6张
boolIList.IsFixedSize
listbox美化第17张listbox美化第18张
{
listbox美化第17张listbox美化第18张
get { return false; }
listbox美化第11张 }

listbox美化第6张
listbox美化第6张
boolIList.IsReadOnly
listbox美化第17张listbox美化第18张
{
listbox美化第17张listbox美化第18张
get { returnIsReadOnly; }
listbox美化第11张 }

listbox美化第6张
listbox美化第6张
voidIList.Remove(objectvalue)
listbox美化第17张listbox美化第18张
{
listbox美化第6张 Remove(value
asListBoxExItem);
listbox美化第11张 }

listbox美化第6张
listbox美化第6张
voidIList.RemoveAt(intindex)
listbox美化第17张listbox美化第18张
{
listbox美化第6张 RemoveAt(index);
listbox美化第11张 }

listbox美化第6张
listbox美化第6张
objectIList.this[intindex]
listbox美化第17张listbox美化第18张
{
listbox美化第6张
get
listbox美化第17张listbox美化第18张
{
listbox美化第6张
return this[index];
listbox美化第11张 }

listbox美化第6张
set
listbox美化第17张listbox美化第18张
{
listbox美化第6张
if(!(value isListBoxExItem))
listbox美化第17张listbox美化第18张
{
listbox美化第6张
throw newArgumentException();
listbox美化第11张 }

listbox美化第6张
this[index] =value asListBoxExItem;
listbox美化第11张 }

listbox美化第11张 }

listbox美化第6张
listbox美化第11张
#endregion
listbox美化第6张
listbox美化第4张listbox美化第5张
ICollection 成员ICollection 成员
listbox美化第6张
listbox美化第6张
voidICollection.CopyTo(Array array, intindex)
listbox美化第17张listbox美化第18张
{
listbox美化第6张 CopyTo((ListBoxExItem[])array, index);
listbox美化第11张 }

listbox美化第6张
listbox美化第6张
intICollection.Count
listbox美化第17张listbox美化第18张
{
listbox美化第17张listbox美化第18张
get { returnCount; }
listbox美化第11张 }

listbox美化第6张
listbox美化第6张
boolICollection.IsSynchronized
listbox美化第17张listbox美化第18张
{
listbox美化第17张listbox美化第18张
get { return false; }
listbox美化第11张 }

listbox美化第6张
listbox美化第6张
objectICollection.SyncRoot
listbox美化第17张listbox美化第18张
{
listbox美化第17张listbox美化第18张
get { return this; }
listbox美化第11张 }

listbox美化第6张
listbox美化第11张
#endregion
listbox美化第6张
listbox美化第4张listbox美化第5张
IEnumerable 成员IEnumerable 成员
listbox美化第6张
listbox美化第6张 IEnumerator IEnumerable.GetEnumerator()
listbox美化第17张listbox美化第18张
{
listbox美化第6张
returnGetEnumerator();
listbox美化第11张 }

listbox美化第6张
listbox美化第11张
#endregion
listbox美化第99张 }

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

listbox美化第1张internalListBox.ObjectCollection OldItems
{
listbox美化第17张listbox美化第18张
get { return base.Items; }
listbox美化第99张 }
listbox美化第1张[Localizable(true)]
listbox美化第1张 [MergableProperty(
false)]
listbox美化第1张 [DesignerSerializationVisibility(
listbox美化第1张 DesignerSerializationVisibility.Content)]
listbox美化第1张
public newListBoxExItemCollection Items
{
listbox美化第17张listbox美化第18张
get { return_items; }
listbox美化第99张 }

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

listbox美化第1张protected override voidOnDrawItem(DrawItemEventArgs e)
{
listbox美化第6张
base.OnDrawItem(e);
listbox美化第6张
listbox美化第6张
if(e.Index != -1 && base.Items.Count > 0)
listbox美化第17张listbox美化第18张
{
listbox美化第6张 System.Diagnostics.Debug.WriteLine(e.State);
listbox美化第6张 Rectangle bounds
=e.Bounds;
listbox美化第6张 ListBoxExItem item
=Items[e.Index];
listbox美化第6张 Graphics g
=e.Graphics;
listbox美化第6张
listbox美化第6张
if((e.State &DrawItemState.Selected)
listbox美化第6张
==DrawItemState.Selected)
listbox美化第17张listbox美化第18张
{
listbox美化第6张 RenderBackgroundInternal(
listbox美化第6张 g,
listbox美化第6张 bounds,
listbox美化第6张 _selectedColor,
listbox美化第6张 _selectedColor,
listbox美化第6张 Color.FromArgb(
200, 255, 255, 255),
listbox美化第6张
0.45f,
listbox美化第6张
true,
listbox美化第6张 LinearGradientMode.Vertical);
listbox美化第11张 }

listbox美化第6张
else
listbox美化第17张listbox美化第18张
{
listbox美化第6张 Color backColor;
listbox美化第6张
if(e.Index % 2 == 0)
listbox美化第17张listbox美化第18张
{
listbox美化第6张 backColor
=_rowBackColor2;
listbox美化第11张 }

listbox美化第6张
else
listbox美化第17张listbox美化第18张
{
listbox美化第6张 backColor
=_rowBackColor1;
listbox美化第11张 }

listbox美化第6张
using(SolidBrush brush = newSolidBrush(backColor))
listbox美化第17张listbox美化第18张
{
listbox美化第6张 g.FillRectangle(brush, bounds);
listbox美化第11张 }

listbox美化第11张 }

listbox美化第6张
listbox美化第6张 Image image
=item.Image;
listbox美化第6张
listbox美化第6张 Rectangle imageRect
= newRectangle(
listbox美化第6张 bounds.X
+ 2,
listbox美化第6张 bounds.Y
+ 2,
listbox美化第6张 bounds.Height
- 4,
listbox美化第6张 bounds.Height
- 4);
listbox美化第6张 Rectangle textRect
= newRectangle(
listbox美化第6张 imageRect.Right
+ 2,
listbox美化第6张 bounds.Y,
listbox美化第6张 bounds.Width
-imageRect.Right - 2,
listbox美化第6张 bounds.Height);
listbox美化第6张
listbox美化第6张
stringtext =item.ToString();
listbox美化第6张 TextFormatFlags formatFlags
=
listbox美化第6张 TextFormatFlags.VerticalCenter;
listbox美化第6张
if(RightToLeft ==RightToLeft.Yes)
listbox美化第17张listbox美化第18张
{
listbox美化第6张 imageRect.X
=bounds.Right -imageRect.Right;
listbox美化第6张 textRect.X
=bounds.Right -textRect.Right;
listbox美化第6张 formatFlags
|=TextFormatFlags.RightToLeft;
listbox美化第6张 formatFlags
|=TextFormatFlags.Right;
listbox美化第11张 }

listbox美化第6张
else
listbox美化第17张listbox美化第18张
{
listbox美化第6张 formatFlags
|=TextFormatFlags.Left;
listbox美化第11张 }

listbox美化第6张
listbox美化第6张
if(image != null)
listbox美化第17张listbox美化第18张
{
listbox美化第6张 g.InterpolationMode
=
listbox美化第6张 InterpolationMode.HighQualityBilinear;
listbox美化第6张 g.DrawImage(
listbox美化第6张 image,
listbox美化第6张 imageRect,
listbox美化第6张
0,
listbox美化第6张
0,
listbox美化第6张 image.Width,
listbox美化第6张 image.Height,
listbox美化第6张 GraphicsUnit.Pixel);
listbox美化第11张 }

listbox美化第6张
listbox美化第6张 TextRenderer.DrawText(
listbox美化第6张 g,
listbox美化第6张 text,
listbox美化第6张 Font,
listbox美化第6张 textRect,
listbox美化第6张 ForeColor,
listbox美化第6张 v formatFlags);
listbox美化第6张
listbox美化第6张
if((e.State &DrawItemState.Focus) ==
listbox美化第6张 DrawItemState.Focus)
listbox美化第17张listbox美化第18张
{
listbox美化第6张 e.DrawFocusRectangle();
listbox美化第11张 }

listbox美化第11张 }

listbox美化第99张 }

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

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

免责声明:文章转载自《listbox美化》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Beetl学习总结(2)——基本用法处理 EF 并发其实就这么简单下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

随便看看

华为 HG526 破解实录(一)Cfg文件加解密工具

几天前,我去中国电信安装E169软件包,并发送了一个华为HG526无线路由猫和一个中兴xxx网络机顶盒(尚未开始制造麻烦)。当然,无线路由猫一如既往地被阉割了。搜索之后,我开始了我的快攻之旅。1.打开catdrop管理页面,使用telecomadmin和nE7jA%5m登录;2.将U盘插入猫。3.开放式管理=˃设备管理、备份配置。4.打开U盘,放下ctce8...

为服务中网关的作用

“API网关”核心组件是架构用于满足此些需求。API网关定位为应用系统服务接口的网关,区别于网络技术的网关,但是原理则是一样。API网关统一服务入口,可方便实现对平台众多服务接口进行管控,对访问服务的身份认证、防报文重放与防数据篡改、功能调用的业务鉴权、响应数据的脱敏、流量与并发控制,甚至基于API调用的计量或者计费等等。...

字符串解压缩类库(zip、GZIP、QuickLz、snappy、lzf、jzlib)介绍

它旨在提供高压缩速度和合理的压缩比=-1){out.write;}字节[]未压缩=输出。到字节数组();--返回提取字符串的字节数组。介绍使用预先选择的解压缩类库-GZIP压缩字符串=“这是一个用于测试的字符串”;ByteArrayOutputStreamout=新的ByteArray输出流();GZipOutputStreamgout=newGZipOut...

如何在Java应用中提交Spark任务?

我丈夫是一个用户定义的ID,作为参数传递给Spark应用程序;Spark初始化后,可以通过SparkContext_ ID和URL通过驱动程序连接到数据库,新版本关联关系的插入归因于互联网时代的信息爆炸。我看到了群友的聊天,了解了SparkLauncher。经过调查,我发现它可以基于Java代码自动提交Spark任务。因为SparkLauncher的类引用了...

【转】MUD教程--巫师入门教程4

在MUD中,为了解决定时触发某种现象,一般有两种方法,一种是通过call_out()延时呼叫,另一种就是通过心跳。于是,对于要跨起离线前后的象做牢这类的事,大多都是采用condition。附:由于大多数MUD里的心跳是每两秒调一次,5+random是5至14次,因此可以看出每一个condition被调用的时间是平均19秒。然后它会按照condition的名字...

Caused by: com.alibaba.druid.pool.DataSourceClosedException: dataSource already closed

春季启动正常启动后,计划任务中的数据库查询报告错误。错误消息如下:1Causedby:org.apache。伊巴提斯。例外情况。PersistenceException:2###错误查询数据库。暂停:org.springframework。jdbc。无法获取JdbcConnection异常:无法获取JDBC连接;3estedexetinisom.alibab...