设计带图标和自定义颜色的ListBox |
|
www.nanhushi.com 佚名 不详 |
在一个点对点文件传输的项目中,我需要显示文件传输的实时信息:传输的文件列表和当前传输的文件,当时我想到了用ListBox,但是但我用了ListBox后,我发现它不能改变控件中文本想的颜色,于是我就想扩展一下ListBox控件------ListBoxEx。
我的目标是给空间加上图标,还要能时时改变控件文本颜色。于是从ListBox派生类
public class ListBoxEx : ListBox {…} | 为了操作方便我为ListBoxEx的每一项设计专门的类ListBoxExItem
public class ListBoxExItem {…} | 为了保持我这个控件与WinForm的标准控件的操作借口一致,我又重新设计了两个集合类:
public class ListBoxExItemCollection : IList, ICollection, IEnumerator {} //这个类相对于标准ListBox中的ObjectCollection,这个类作为ListBoxEx中的Items属性的类型
public class SelectedListBoxExItemCollection : : IList, ICollection, IEnumerator{} //这个类相对于标准ListBox中的SelectedObjectCollection,这个类作为ListBoxEx中的SelectedItems属性的类型 | 下面看两个集合类的实现:
ListBoxExItemCollection的实现:为了做到对集合(Items)的操作能够及时反映到ListBoxEx的控件中所以,此类只是对ListBox中Items(ObjectCollection类型)作了一层包装,就是把ListBox中Items属性的所有方法的只要是object类型的参数都转换成ListBoxExItem,比如:
public void Remove(ListBoxExItem item) { this._Items.Remove(item); //_Items为ObjectCollection类型 }
public void Insert(int index, ListBoxExItem item) { this._Items.Insert(index, item); }
public int Add(ListBoxExItem item) { return this._Items.Add(item); } | 由上可知,ListBoxExItemCollection中有一个构造函数来传递ListBox中的Items对象
private ObjectCollection _Items;
public ListBoxExItemCollection(ObjectCollection baseItems) { this._Items = baseItems; } | 而SelectedListBoxExItemCollection类的实现也用同样的方法,只不过是对SelectedObjectCollection包装罢了。
集合实现后,再来看ListBoxExItem的实现:
为了使它支持图标和多种颜色添加如下成员
private int _ImageIndex;
public int ImageIndex { get { return this._ImageIndex; } set { this._ImageIndex = value;} }
private Color _ForeColor;
public Color ForeColor { get{ return this._ForeColor;} set { this._ForeColor = value; this.Parent.Invalidate(); } } | 当然还有:
private string _Text;
public string Text { get { return this._Text; } set { this._Text = value; } } | 为了控件能正确显示此项的文本,还必须重写ToString()方法
public override string ToString() { return this._Text; } | 再看ListBoxEx的实现:
为了使控件能够自我绘制,所以:DrawMode = DrawMode.OwnerDrawFixed;
为了覆盖基类的Items等相关属性添加
private ListBoxExItemCollection _Items; //在构造函数中创建 | 同时还需要重写属性Items:
new public ListBoxExItemCollection Items { get { return this._Items; } }
new public ListBoxExItem SelectedItem //强制转换为ListBoxExItem { get{ return base.SelectedItem as ListBoxExItem;} set{ base.SelectedItem = value;} }
new public SelectedListBoxExItemCollection SelectedItems //重新包装SelectedItems { get { return new SelectedListBoxExItemCollection(base.SelectedItems); } } | 为了支持图标,添加一个图像列表imagelist
private ImageList imageList;
public ImageList ImageList { get { return this.imageList; } set { this.imageList = value; this.Invalidate();//图像列表改变后马上更新控件 } } | 而此控件的核心却在一个方法OnDrawItem,这个方法每当控件的项需要重绘时就被调用
protected override void OnDrawItem(System.Windows.Forms.DrawItemEventArgs pe) { pe.DrawBackground(); //画背景 pe.DrawFocusRectangle(); //画边框 Rectangle bounds = pe.Bounds;
// Check whether the index is valid
if(pe.Index >= 0 && pe.Index < base.Items.Count) { ListBoxExItem item = this.Items[pe.Index]; //取得需要绘制项的引用 int iOffset = 0;
// If the image list is present and the image index is set, draw the image
if(this.imageList != null) { if (item.ImageIndex > -1 && item.ImageIndex < this.imageList.Images.Count) { this.imageList.Draw(pe.Graphics, bounds.Left, bounds.Top, bounds.Height, bounds.Height, item.ImageIndex); //绘制图标 } iOffset += bounds.Height;//this.imageList.ImageSize.Width; }
// Draw item text
pe.Graphics.DrawString(item.Text, pe.Font, new SolidBrush(item.ForeColor),bounds.Left + iOffset, bounds.Top); //根据项的颜色绘制文本
} base.OnDrawItem(pe); } } | 到此为止,ListBoxEx以完整的实现,并且支持可视化设计。
|
|
|
文章录入:杜斌 责任编辑:杜斌 |
|
上一篇文章: C语言程序编辑学习篇—编程者说之C语言 下一篇文章: 用C设计在局域网发送短信的程序 |
【字体:小 大】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口】 |
|
|