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