[C#.NET][Winform] 製作不同顏色相間隔的 ListBox

  • 21369
  • 0

[C#.NET][Winform] 製作不同顏色相間隔的 ListBox

利用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 實作的結果如下:

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的底色相間,我需要兩個顏色

/// <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; }
}

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

/// <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項目出現不一樣的顏色
public Color SelectRowColor
{
    get { return _SelectRowColor; }
    set
    {
        _SelectRowColor = value;
        this.Invalidate();
    }
}

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

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

重繪內容如下

{
    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的模式

{
    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

若有謬誤,煩請告知,新手發帖請多包涵


Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET

Image result for microsoft+mvp+logo