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

后端 未结 6 1520
走了就别回头了
走了就别回头了 2020-12-15 17:44

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.

<
相关标签:
6条回答
  • 2020-12-15 17:45

    This should get you started.

    Change the combobox DrawMode property to OwnerDrawFixed, and handle the DrawItem event:

    private void comboBox1_DrawItem(object sender, DrawItemEventArgs e)
    {
        int index = e.Index >= 0 ? e.Index : 0;
        var brush = Brushes.Black;
        e.DrawBackground();
        e.Graphics.DrawString(comboBox1.Items[index].ToString(), e.Font, brush, e.Bounds, StringFormat.GenericDefault);
        e.DrawFocusRectangle();
    }
    

    The background color will be right but the style of the box will be flat, not the usual 3D style.

    0 讨论(0)
  • 2020-12-15 17:52

    I played around with this for a while and didn't want to do anything too involved. Those ideas above probably work but all I did was change the flatStyle property from "standard" to "flat".

    Although not perfect, it at least changes the background that grey/disabled look to white.

    You can see the comparison here:

    Heating Source #1 > DropdownList > flat (the final decision since dropdown was allowing users to enter bad data)

    Heater Source #2 > Dropdown > Standard (the default which looks nice)

    Housing Type > Dropdown > Flat

    Heating Source #1 Vendor > DropdownList > Standard (the default which looks disabled grey)

    0 讨论(0)
  • 2020-12-15 17:52

    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
    
    0 讨论(0)
  • 2020-12-15 17:57

    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 ();
    }
    
    0 讨论(0)
  • 2020-12-15 18:02
        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();
            }
        }
    
    0 讨论(0)
  • 2020-12-15 18:06

    Since you lose the 3D effects anyway with Igby Largeman's solution you're better off changing the FlatStyle property to Flat. The background color seems to be obeyed even in Windows 7 that way, and without re-implementing any low-level events.

    I would consider this a bug on Microsoft's part...

    0 讨论(0)
提交回复
热议问题