余小章 @ 大內聖殿
祕訣無它, 唯勤而已, by 余小章

导航

 

利用ListBox.DrawItem事件我們可以重繪我們自己想要的ListBox顯示樣式,要先設定 ListBox.DrawMode = DrawMode.OwnerDrawFixed

請參考 http://msdn.microsoft.com/zh-tw/library/system.windows.forms.listbox.drawitem%28en-us,VS.90%29.aspx 實作的結果如下:

string[] array = new string[] { "余小章", "yao", "點部落", "台北市", "GGYY" };
public Form1()
{
    InitializeComponent();
    this.listBox1.DrawMode = DrawMode.OwnerDrawFixed;
    this.listBox1.DrawItem += new DrawItemEventHandler(listBox1_DrawItem);
    this.listBox1.DataSource = array;
}

void listBox1_DrawItem(object sender, DrawItemEventArgs e)
{
    ListBox list = (ListBox)sender;

    // Draw the background of the ListBox control for each item.
    e.DrawBackground();
    // Define the default color of the brush as black.
    Brush myBrush = Brushes.Black;

    // Determine the color of the brush to draw each item based 
    // on the index of the item to draw.
    switch (e.Index)
    {
        case 0:
            myBrush = Brushes.Red;
            break;
        case 1:
            myBrush = Brushes.Orange;
            break;
        case 2:
            myBrush = Brushes.Purple;
            break;
    }

    // Draw the current item text based on the current Font 
    // and the custom brush settings.
    e.Graphics.DrawString(list.Items[e.Index].ToString(),
        e.Font, myBrush, e.Bounds, StringFormat.GenericDefault);
    // If the ListBox has focus, draw a focus rectangle around the selected item.
    e.DrawFocusRectangle();
}

image


現在我想要讓ListBox的底色相間,我需要兩個顏色

private Color _RowColor1 = Color.CornflowerBlue;
/// <summary>
/// 第一列的顏色
/// </summary>
public Color RowColor1
{
    get { return _RowColor1; }
    set { _RowColor1 = value; }
}

private Color _RowColor2 = Color.PaleGreen;
/// <summary>
/// 第二列的顏色
/// </summary>
public Color RowColor2
{
    get { return _RowColor2; }
    set { _RowColor2 = value; }
}

我又想要讓原本的顏色有漸層感覺,再來兩隻顏色

private Color _RowGradualColor1 = Color.Thistle;
/// <summary>
/// 第一列的漸層色
/// </summary>
public Color RowGradualColor1
{
    get { return _RowGradualColor1; }
    set { _RowGradualColor1 = value; }
}
private Color _RowGradualColor2 = Color.DarkKhaki;
/// <summary>
/// 第二列的漸層色
/// </summary>
public Color RowGradualColor2
{
    get { return _RowGradualColor2; }
    set { _RowGradualColor2 = value; }
}

要讓選擇的ListBox項目出現不一樣的顏色
private Color _SelectRowColor = Color.White;
public Color SelectRowColor
{
    get { return _SelectRowColor; }
    set
    {
        _SelectRowColor = value;
        this.Invalidate();
    }
}

我想要讓使用者決定要不要使用漸層色

private bool _IsGradualColor = true;
/// <summary>
/// 是否使用漸層筆刷
/// </summary>
public bool IsGradualColor
{
    get { return _IsGradualColor; }
    set
    {
        _IsGradualColor = value;
        this.Invalidate();
    }
}

重繪內容如下

void listBox1_DrawItem(object sender, DrawItemEventArgs e)
{
    ListBox list = (ListBox)sender;
    if (list.Items.Count <= 0)
        return;

    //定義框的大小
    Rectangle rec = new Rectangle(0, 0, list.Width, list.Height);

    //定義一般筆刷
    SolidBrush brushRow1 = new SolidBrush(this.RowColor1);
    SolidBrush brushRow2 = new SolidBrush(this.RowColor2);

    //定義漸層筆刷
    LinearGradientBrush linBrushRow1 = new LinearGradientBrush(rec, this.RowColor1, this.RowGradualColor1, LinearGradientMode.BackwardDiagonal);
    LinearGradientBrush linBrushRow2 = new LinearGradientBrush(rec, this.RowColor2, this.RowGradualColor2, LinearGradientMode.BackwardDiagonal);

    //選筆刷
    Brush brush;
    if (this.IsGradualColor)
    {
        if (e.Index % 2 == 0)
            brush = linBrushRow1;
        else
            brush = linBrushRow2;
    }
    else
    {
        if (e.Index % 2 == 0)
            brush = brushRow1;
        else
            brush = brushRow2;
    }
    //畫框
    e.Graphics.FillRectangle(brush, e.Bounds);
    bool selected = ((e.State & DrawItemState.Selected) == DrawItemState.Selected) ? true : false;
    if (selected)
    {
        e.Graphics.FillRectangle(new SolidBrush(this.SelectRowColor), e.Bounds);
    }
    //畫字
    e.Graphics.DrawString(list.Items[e.Index].ToString(), this.Font, Brushes.Black, e.Bounds);
    //畫焦點框
    e.DrawFocusRectangle();
}


在form1裡呼叫,我用 RadioButton 來切換ListBox的模式

private void Form1_Load(object sender, EventArgs e)
{
    this.listBox1.SuspendLayout();
    if (this.radioButton_None.Checked)
    {
        this.listBox1.DrawMode = DrawMode.Normal;
        this.IsGradualColor = false;
    }
    else if (this.radioButton_Gernal.Checked)
    {
        this.IsGradualColor = false;
        this.listBox1.DrawMode = DrawMode.OwnerDrawFixed;
        this.listBox1.DrawItem += new DrawItemEventHandler(listBox1_DrawItem);
    }
    else if (this.radioButton_Gradual.Checked)
    {
        this.IsGradualColor = true;
        this.listBox1.DrawMode = DrawMode.OwnerDrawFixed;
        this.listBox1.DrawItem += new DrawItemEventHandler(listBox1_DrawItem);
    }
    this.listBox1.DataSource = array;
    this.listBox1.ResumeLayout(false);
}

private void radioButton_CheckedChanged(object sender, EventArgs e)
{
    RadioButton radio = (RadioButton)sender;
    this.listBox1.SuspendLayout();

    switch (radio.Name)
    {
        case "radioButton_None":
            if (radio.Checked)
            {
                this.listBox1.DrawItem -= new DrawItemEventHandler(listBox1_DrawItem);
                this.listBox1.DrawMode = DrawMode.Normal;
                this.listBox1.DrawItem += new DrawItemEventHandler(listBox1_DrawItem);

            }
            break;
        case "radioButton_Gernal":
            if (radio.Checked)
            {
                this.listBox1.DrawItem -= new DrawItemEventHandler(listBox1_DrawItem);
                this.IsGradualColor = false;
                this.listBox1.DrawMode = DrawMode.OwnerDrawFixed;
                this.listBox1.DrawItem += new DrawItemEventHandler(listBox1_DrawItem);
            }
            break;
        case "radioButton_Gradual":
            if (radio.Checked)
            {
                this.listBox1.DrawItem -= new DrawItemEventHandler(listBox1_DrawItem);
                this.IsGradualColor = true;
                this.listBox1.DrawMode = DrawMode.OwnerDrawFixed;
                this.listBox1.DrawItem += new DrawItemEventHandler(listBox1_DrawItem);
            }
            break;
    }
    if (radio.Checked)
    {
        this.listBox1.DataSource = null;
        this.listBox1.DataSource = array;
    }
    this.listBox1.ResumeLayout(false);
}

執行結果如下:

imageimageimage


後記:DrawListBox.zip

基本上重繪是每一個控制項所擁有的功能,當需要重新定義呈現樣式時,上述方法是一個很簡單的流程做法,主要是學習比刷的用法,跟上述相似的主題有以下:

[C#.Net][Winform] 具有圖形選項的 ListBox

[C#.Net][Winform] 具有圖形選項的 ComboBox

posted on 2011-12-27 15:24  余小章  阅读(766)  评论(0编辑  收藏  举报