首页 > 开发 > 综合 > 正文

C#设计带图标和自定义颜色的ListBox

2024-07-21 02:24:39
字体:
来源:转载
供稿:网友

  在一个点对点文件传输的项目中,我需要显示文件传输的实时信息:传输的文件列表和当前传输的文件,当时我想到了用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以完整的实现,并且支持可视化设计。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表