Ⅰ概要說明
ComboBox 是最常用的窗體控件之一,在各種開發中,我麼有可能需要將各種各樣的對象放到ComboBox 上去。爲此微軟爲ComboBox提供了極據效力的擴展功能來應付這種需求。在一次針對Excel的應用開發中,爲了能像Excel那樣爲單元格設定邊框樣式,我製作了下面這樣的下拉框。感謝.NET讓這一切變得非常容易和方便。
Ⅱ示例:
爲了能夠實現自定義,我們首先需要將ComboBox.DrawMode 屬性設置爲OwnerDrawVariable。在這種模式下,當ComboBox需要重畫時,將觸發ComboBox.DrawItem和ComboBox.MeasureItem 事件。在MeasureItem 事件內我們可以指定要繪製的項的大小,而在DrawItem 事件我們則可以按照需要來繪製對應的項目。
事實上,當你指定了OwnerDrawVariable後,實現DrawItem 事件也是必須的,否則你有可能得到一個只有框架的ComboBox。以下是上述兩個ComboBox的關鍵代碼。
void ExcelLineCombox_DrawItem(object sender, DrawItemEventArgs e)
{
if (this.Items.Count <= 0) return;
if (_LineList[e.Index].BorderStyle == Excel.XlLineStyle.xlLineStyleNone)
{
//「なし」文字を描畫します
SolidBrush myBrush = new SolidBrush(_LineList[e.Index].BorderColor);
e.Graphics.DrawString("なし", this.Font, myBrush,
new RectangleF(e.Bounds.X + 2, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height));
}
else
{
//罫線ペンを定義します
Pen myPen = MakeExcelBorderPen( _LineList[e.Index]);
//罫線を描畫します
if (_LineList[e.Index].BorderStyle == Excel.XlLineStyle.xlDouble)
{
e.Graphics.DrawLine(myPen, e.Bounds.X + 2, e.Bounds.Top + e.Bounds.Height / 2 - 1,
e.Bounds.Width - 2, e.Bounds.Top + e.Bounds.Height / 2 - 1);
e.Graphics.DrawLine(myPen, e.Bounds.X + 2, e.Bounds.Top + e.Bounds.Height / 2 + 1,
e.Bounds.Width - 2, e.Bounds.Top + e.Bounds.Height / 2 + 1);
}
else
{
e.Graphics.DrawLine(myPen, e.Bounds.X + 2, e.Bounds.Top + e.Bounds.Height / 2,
e.Bounds.Width - 2, e.Bounds.Top + e.Bounds.Height / 2);
}
}
}
可以想象_LineList是一個定義了ComboBox內所有項目的集合,在這個程序內塔描述了ComboBox內每個項目內線條的顏色和樣式。該集合的大小往往就是ComboBox的項目數。
void ExcelColorCombox_DrawItem(object sender, DrawItemEventArgs e)
{
if (this.Items.Count <= 0) return;
// Draw color hint
Rectangle colorRectangle = new Rectangle(2, e.Bounds.Top + 1, e.Bounds.Height * 2, e.Bounds.Height - 2);
e.Graphics.FillRectangle(new SolidBrush(_ExcelKnownColor[e.Index]), colorRectangle);
if (e.Index > 0)
{
// カラー名を描畫します
e.Graphics.DrawString(_ExcelKnownColorName[e.Index], this.Font, System.Drawing.Brushes.Black,
new RectangleF(e.Bounds.X + colorRectangle.Width, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height));
}
else
{
if (useCustomColor)
//カスタマイズ色が指定された場合に
e.Graphics.DrawString("カスタマイズ", this.Font, System.Drawing.Brushes.Black,
new RectangleF(e.Bounds.X + colorRectangle.Width, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height));
else
//カスタマイズ色が指定されなかった場合に
e.Graphics.DrawString("カスタマイズ...", this.Font, System.Drawing.Brushes.Black,
new RectangleF(e.Bounds.X + 2, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height));
}
}