程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> 關於C# >> 設計帶圖標和自定義顏色的ListBox

設計帶圖標和自定義顏色的ListBox

編輯:關於C#

在一個點對點文件傳輸的項目中,我需要顯示文件傳輸的實時信息:傳輸的文件列表和當前傳輸的文件,當時我想到了用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以完整的實現,並且支持可視化設計。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved