[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();
}
現在我想要讓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);
}
執行結果如下:
基本上重繪是每一個控制項所擁有的功能,當需要重新定義呈現樣式時,上述方法是一個很簡單的流程做法,主要是學習比刷的用法,跟上述相似的主題有以下:
[C#.Net][Winform] 具有圖形選項的 ListBox
[C#.Net][Winform] 具有圖形選項的 ComboBox
若有謬誤,煩請告知,新手發帖請多包涵
Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET