在一個點(diǎn)對點(diǎn)文件傳輸?shù)捻?xiàng)目中,我需要顯示文件傳輸?shù)膶?shí)時信息:傳輸?shù)奈募斜砗彤?dāng)前傳輸?shù)奈募?dāng)時我想到了用listbox,但是但我用了listbox后,我發(fā)現(xiàn)它不能改變控件中文本想的顏色,于是我就想擴(kuò)展一下listbox控件------listboxex。
我的目標(biāo)是給空間加上圖標(biāo),還要能時時改變控件文本顏色。于是從listbox派生類
public class listboxex : listbox {…}
為了操作方便我為listboxex的每一項(xiàng)設(shè)計(jì)專門的類listboxexitem
public class listboxexitem {…}
為了保持我這個控件與winform的標(biāo)準(zhǔn)控件的操作借口一致,我又重新設(shè)計(jì)了兩個集合類:
public class listboxexitemcollection : ilist, icollection, ienumerator {}
//這個類相對于標(biāo)準(zhǔn)listbox中的objectcollection,這個類作為listboxex中的items屬性的類型
public class selectedlistboxexitemcollection : : ilist, icollection, ienumerator{}
//這個類相對于標(biāo)準(zhǔn)listbox中的selectedobjectcollection,這個類作為listboxex中的selecteditems屬性的類型
下面看兩個集合類的實(shí)現(xiàn):
listboxexitemcollection的實(shí)現(xiàn):為了做到對集合(items)的操作能夠及時反映到listboxex的控件中所以,此類只是對listbox中items(objectcollection類型)作了一層包裝,就是把listbox中items屬性的所有方法的只要是object類型的參數(shù)都轉(zhuǎn)換成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中有一個構(gòu)造函數(shù)來傳遞listbox中的items對象
private objectcollection _items;
public listboxexitemcollection(objectcollection baseitems)
{
this._items = baseitems;
}
而selectedlistboxexitemcollection類的實(shí)現(xiàn)也用同樣的方法,只不過是對selectedobjectcollection包裝罷了。
集合實(shí)現(xiàn)后,再來看listboxexitem的實(shí)現(xiàn):
為了使它支持圖標(biāo)和多種顏色添加如下成員
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();
}
}
當(dāng)然還有:
private string _text;
public string text
{
get { return this._text; }
set { this._text = value; }
}
為了控件能正確顯示此項(xiàng)的文本,還必須重寫tostring()方法
public override string tostring()
{
return this._text;
}
再看listboxex的實(shí)現(xiàn):
為了使控件能夠自我繪制,所以:drawmode = drawmode.ownerdrawfixed;
為了覆蓋基類的items等相關(guān)屬性添加
private listboxexitemcollection _items; //在構(gòu)造函數(shù)中創(chuàng)建
同時還需要重寫屬性items:
new public listboxexitemcollection items
{
get
{
return this._items;
}
}
new public listboxexitem selecteditem //強(qiáng)制轉(zhuǎn)換為listboxexitem
{
get{ return base.selecteditem as listboxexitem;}
set{ base.selecteditem = value;}
}
new public selectedlistboxexitemcollection selecteditems //重新包裝selecteditems
{
get
{
return new selectedlistboxexitemcollection(base.selecteditems);
}
}
為了支持圖標(biāo),添加一個圖像列表imagelist
private imagelist imagelist;
public imagelist imagelist
{
get { return this.imagelist; }
set
{
this.imagelist = value;
this.invalidate();//圖像列表改變后馬上更新控件
}
}
而此控件的核心卻在一個方法ondrawitem,這個方法每當(dāng)控件的項(xiàng)需要重繪時就被調(diào)用
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]; //取得需要繪制項(xiàng)的引用
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); //繪制圖標(biāo)
}
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); //根據(jù)項(xiàng)的顏色繪制文本
}
base.ondrawitem(pe);
}
}
到此為止,listboxex以完整的實(shí)現(xiàn),并且支持可視化設(shè)計(jì)。
新聞熱點(diǎn)
疑難解答
圖片精選