Update:
Custom drawing a DataGridViewComboBox
is a little involved. In fact it consists of four different drawing cases:
For the unfocused cells you need to code the CellPainting
event:
private void dataGridView1_CellPainting(object sender,
DataGridViewCellPaintingEventArgs e)
{
// drawstuff nr 1: draw the unfocused cell
}
When the cell has focus the actual DataGridViewComboBoxEditingControl
(which is a direct descendent from ComboBox
) is created and shown.
You need get a handle to it (in the EditingControlShowing
event) and then should code three more cases in its DrawItem
event:
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
}
}
}
A few notes on the various paint codes:
drawstuff 1: Here you should draw an arrow after drawing the text. For this best make use of the ComboBoxRenderer.DrawDropDownButton
method. You will need to know the position and size, SystemInformation.VerticalScrollBarWidth
should help with that.. note that the TextRenderer.DrawText
not only lets you use nice TextFormatFlags
to help with alignment, but also a Backcolor
!
drawstuff 2: Note that the ComboBox unfortunately doesn't pick up the BackColor of its cell. It will still help to set it, so you can refer to it as the target color. like in the following darw codes you will wnat to use a combination of e.Graphics.DrawXxx
calls and TextRenderer.DrawText
. For easier reference to the DGV cells it belongs to, you may want to store the CurrentCell
in the reference ComboBox
's Tag
when setting it in the EditingControlShowing
event.
drawstuff 3: The selected Item may have special colors for font and background
drawstuff 4: The regular item is just that: rather regular..
The code below is the original version of my answer, only covering cases 3&4:
Here is a short example to show you how to paint a DataGridViewComboBox
. Note that I only show the bare minimum and didn't go into painting the colored squares..:
We start by defining a class level reference to the cell:
ComboBox theBoxCell = null;
In the EditingControlShowing
we set the reference, add an event handler and set it to an owner-draw mode:
private void dataGridView1_EditingControlShowing(object sender,
DataGridViewEditingControlShowingEventArgs e)
{
theBoxCell = (ComboBox) e.Control;
theBoxCell.DrawItem += theBoxCell_DrawItem;
theBoxCell.DrawMode = DrawMode.OwnerDrawVariable;
}
Finally we add the draw code:
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);
}
We could have added the draw code in a linq to the event hook-up as well..
Here is the result:
