How to change combobox background color (not just the drop down list part)

Viewed 61103

In a winform application running on windows 7 I want the change the background color of a combobox to highlight it. The comboxbox has a DropDownStyle of DropDownList.

When I programmatically change the BackColor property to Red, only the background of the actual drop down list is changed to Red. When the drop down list is not opened, the combobox background displaying the selected value remains grey. What can I do so it becomes red too?

Setting the BackColor property works fine when app is run on Windows XP

6 Answers

Igby Largeman's answer got me 95% of the way there. And credit to Sasha Bond for the Brush colouring for setting the HighlightText colour when selected.

Some improvements I made to get me to 100% are adding brush colour from the ComboBox's ForeColor and handling when the index is -1 (and setting it to -1 to start with so it behaves exactly like a normal dropdownstyle ComboBox).

Best of all, when setting this back to a standard dropdown style, it still behaves normally.

private void comboBox1_DrawItem ( object sender, DrawItemEventArgs e )
{
  int index = e.Index >= 0 ? e.Index : -1;
  Brush brush = ( ( e.State & DrawItemState.Selected ) > 0 ) ? SystemBrushes.HighlightText : new SolidBrush ( comboBox1.ForeColor );
  e.DrawBackground ();
  if ( index != -1 )
  {
    e.Graphics.DrawString ( comboBox1.Items[index].ToString (), e.Font, brush, e.Bounds, StringFormat.GenericDefault );
  }
  e.DrawFocusRectangle ();
}
    private void comboBox1_DrawItem(object sender, DrawItemEventArgs e)
    {
        var cmb = (ComboBox) sender;
        if (cmb == null) return;

        if (e.Index % 2 == 0)
        {
            e.Graphics.FillRectangle(SystemBrushes.Window, e.Bounds);
            e.Graphics.DrawString(cmb.Items[e.Index].ToString(), cmb.Font, SystemBrushes.GrayText, e.Bounds);
        }
        else
        {
            e.DrawBackground();

            // change background color
            e.Graphics.FillRectangle(Brushes.AntiqueWhite, e.Bounds);

            // change foreground color
            Brush brush = ((e.State & DrawItemState.Selected) > 0) ? SystemBrushes.HighlightText : SystemBrushes.ControlText;

            e.Graphics.DrawString(cmb.Items[e.Index].ToString(), cmb.Font, brush, e.Bounds);
            e.DrawFocusRectangle();
        }
    }

Here is what i used for a vb project for another beginner that might be interested. One can use the sender of the event as the combobox that triggered it. By casting it, you can have access to the elements of the list. I also changed the graphics TextRenderingHint for better font display.

Private Sub PaintComboBoxItem(sender As Object, e As DrawItemEventArgs)
    Dim combobox As ComboBox = sender
    Dim index As Integer = If(e.Index >= 0, e.Index, 0)
    Dim brush As Brush = If(combobox.Enabled,
                                New SolidBrush(m_UITheme.TitleColor),
                                New SolidBrush(m_UITheme.White))
    e.Graphics.SmoothingMode = SmoothingMode.HighQuality
    e.Graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit
    e.DrawBackground()
    e.Graphics.DrawString(combobox.Items(index).ToString(), combobox.Font, brush, e.Bounds, StringFormat.GenericDefault)
    e.DrawFocusRectangle()
End Sub
Related