更新:
自定义绘制DataGridViewComboBox 有点复杂。实际上它由四种不同的绘图案例组成:
对于未聚焦的单元格,您需要编写CellPainting 事件:
private void dataGridView1_CellPainting(object sender,
DataGridViewCellPaintingEventArgs e)
{
// drawstuff nr 1: draw the unfocused cell
}
当单元格具有焦点时,实际的DataGridViewComboBoxEditingControl(它是ComboBox 的直接后代)被创建并显示。
您需要获取它的句柄(在 EditingControlShowing 事件中),然后应该在其 DrawItem 事件中再编写三个案例:
void theBoxCell_DrawItem(object sender, DrawItemEventArgs e)
{
if (e.Index < 0)
{
// drawstuff 2: draw the undropped top portion
}
else
{
if ((e.State & DrawItemState.Selected) != DrawItemState.None
{
// drawstuff 3: draw a selected item
}
else
{
// drawstuff 4: draw an unselected item
}
}
}
关于各种油漆代码的几点说明:
-
drawstuff 1:在这里您应该在绘制文本后绘制一个箭头。为此,最好使用ComboBoxRenderer.DrawDropDownButton 方法。您需要知道位置和大小,SystemInformation.VerticalScrollBarWidth 应该对此有所帮助。请注意,TextRenderer.DrawText 不仅可以让您使用漂亮的TextFormatFlags 来帮助对齐,还可以使用Backcolor!
drawstuff 2:请注意,遗憾的是 ComboBox 没有拾取其单元格的 BackColor。它仍然有助于设置它,因此您可以将其称为目标颜色。就像在下面的 darw 代码中一样,您将需要使用 e.Graphics.DrawXxx 调用和 TextRenderer.DrawText 的组合。为了更方便地引用它所属的 DGV 单元,您可能希望在 EditingControlShowing 事件中设置 CurrentCell 时将其存储在引用 ComboBox 的 Tag 中。
drawstuff 3:所选项目可能具有特殊的字体和背景颜色
drawstuff 4:常规项目就是这样:相当常规..
下面的代码是我的答案的原始版本,只涵盖案例3&4:
下面是一个简短的示例,向您展示如何绘制DataGridViewComboBox。请注意,我只展示了最低限度,并没有画彩色方块..:
我们首先定义一个对单元格的类级引用:
ComboBox theBoxCell = null;
在EditingControlShowing 中我们设置引用,添加事件处理程序并将其设置为所有者绘制模式:
private void dataGridView1_EditingControlShowing(object sender,
DataGridViewEditingControlShowingEventArgs e)
{
theBoxCell = (ComboBox) e.Control;
theBoxCell.DrawItem += theBoxCell_DrawItem;
theBoxCell.DrawMode = DrawMode.OwnerDrawVariable;
}
最后我们添加绘制代码:
void theBoxCell_DrawItem(object sender, DrawItemEventArgs e)
{
if (e.Index < 0) return;
string t = theBoxCell.Items[e.Index].ToString();
using (SolidBrush brush = new SolidBrush(
(e.State & DrawItemState.Selected) != DrawItemState.None ?
Color.LightCyan : Color.LightGray))
e.Graphics.FillRectangle(brush, e.Bounds);
e.DrawFocusRectangle();
e.Graphics.DrawString(t, Font, Brushes.DarkGoldenrod, e.Bounds.X + 6, e.Bounds.Y + 1);
}
我们也可以将 linq 中的绘制代码添加到事件挂钩中......
结果如下: