Ⅰ概要说明
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));
}
}