Click here to Skip to main content
15,884,388 members
Articles / Desktop Programming / Windows Forms
Tip/Trick

Ownerdrawn ComboBox Example

Rate me:
Please Sign up or sign in to vote.
5.00/5 (10 votes)
5 Jul 2013CPOL2 min read 58.3K   10   11
A sample owner-drawn ComboBox
This tip shows how to change the look of the combobox dropdown list using ownerdrawn ComboBoxes.

Background

So there I was, rummaging around Q&A when I encountered OliveiraGui who had a question about how to change the look of the combobox dropdown list (more specifically, the border color).

He had discovered that there were no properties to change that, and my reply to him was that it could be done, but that he had to ownerdraw the ComboBox to do it, and I gave him a few examples of ownerdrawn comboboxes.

Painting your own ComboBox is not really that hard, nor is it that complicated or requires a lot of code. The important part is knowing how to do it. It helps if you have meddled around with drawing in GDI+ or if you have done a fair amount of custom control development.

Afterwards, I thought about it, and I found the question interesting enough to do a small sample for him.

The thing is that even with owner-drawing, it's not really that easy to get access to the dropdown window itself. But it's quite easy to change the appearance of the individual items and thus mimic that the entire window has been changed.

So here is a ComboBox where you can change the BorderColor and BackColor of the dropdown list. For demonstration purposes, I've made the default color values red and yellow. If you were to use this code in a real project, it would probably be a good idea to change that to black and white.

If you study the code, you will see that it is also very easy to change the appearance of the individual items in the dropdown list, e.g., the forecolor, font, etc. But I leave that up to you as a follow-up exercise.

The Code

C#
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;

namespace OwnerDrawnComboBoxTest
{
    [ToolboxBitmap(typeof(ComboBox))]
    class ComboBoxEx : ComboBox
    {
        public ComboBoxEx()
        {
            this.DrawMode = DrawMode.OwnerDrawFixed;
            this.DrawItem += ComboBoxEx_DrawItem;
            this.DropDownBorderColor = Color.Red;
            this.DropDownBackColor = Color.Yellow;
        }

        [Category("Appearance")]
        [Description("The border color of the drop down list")]
        [DefaultValue(typeof(Color), "Red")]
        public Color DropDownBorderColor { get; set; }

        [Category("Appearance")]
        [Description("The background color of the drop down list")]
        [DefaultValue(typeof(Color), "Yellow")]
        public Color DropDownBackColor { get; set; }

        private void ComboBoxEx_DrawItem(object sender, DrawItemEventArgs e)
        {
            if (e.Index < 0)
                return;

            if ((e.State & DrawItemState.ComboBoxEdit) == DrawItemState.ComboBoxEdit)
                return;

            // Draw the background of the item
            if (
                ((e.State & DrawItemState.Focus) == DrawItemState.Focus) ||
                ((e.State & DrawItemState.Selected) == DrawItemState.Selected) ||
                ((e.State & DrawItemState.HotLight) == DrawItemState.HotLight)
               )
            {
                e.DrawBackground();
            }
            else
            {
                using (Brush backgroundBrush = new SolidBrush(DropDownBackColor))
                {
                    e.Graphics.FillRectangle(backgroundBrush, e.Bounds);
                }
            }

            //Draw item text
            e.Graphics.DrawString(Items[e.Index].ToString(), this.Font, Brushes.Black,
              new RectangleF(e.Bounds.X, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height));

            // Draw the focus rectangle if the mouse hovers over an item
            if ((e.State & DrawItemState.Focus) == DrawItemState.Focus)
                e.DrawFocusRectangle();

            //Draw the border around the whole DropDown area
            using (Pen borderPen = new Pen(DropDownBorderColor, 1))
            {
                Point start;
                Point end;

                if (e.Index == 0)
                {
                    //Draw top border
                    start = new Point(e.Bounds.Left, e.Bounds.Top);
                    end = new Point(e.Bounds.Left + e.Bounds.Width - 1, e.Bounds.Top);
                    e.Graphics.DrawLine(borderPen, start, end);
                }

                //Draw left border
                start = new Point(e.Bounds.Left, e.Bounds.Top);
                end = new Point(e.Bounds.Left, e.Bounds.Top + e.Bounds.Height - 1);
                e.Graphics.DrawLine(borderPen, start, end);

                //Draw Right border
                start = new Point(e.Bounds.Left + e.Bounds.Width - 1, e.Bounds.Top);
                end = new Point(e.Bounds.Left + e.Bounds.Width - 1, 
                                e.Bounds.Top + e.Bounds.Height - 1);
                e.Graphics.DrawLine(borderPen, start, end);

                if (e.Index == Items.Count - 1)
                {
                    //Draw bottom border
                    start = new Point(e.Bounds.Left, e.Bounds.Top + e.Bounds.Height - 1);
                    end = new Point(e.Bounds.Left + e.Bounds.Width - 1, 
                                    e.Bounds.Top + e.Bounds.Height - 1);
                    e.Graphics.DrawLine(borderPen, start, end);
                }
            }
        }
    }
}

History

  • Version 1.03 - Added Using
  • Version 1.02 - Added check for Index=-1 and State=ComboBoxEdit - That is necessary if the ComboBox style is DropDownList
  • Version 1.01 - Changed the testing of the e.State flag
  • Version 1.00 - Initial release

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Sweden Sweden
Born in Copenhagen, Denmark
Have been living in Paris, France and L.A., The United States
Now live in Stockholm, Sweden

Started programming when I got my first VIC 20, and a few months later on Commodore 64. Those were the days!

Studied programming at the Copenhagen Engineering Academy

Professional console, winforms and webforms programming in Comal, x86 Assembler, Fortran, Pascal, Delphi, Visual Basic 3 through 6, Classic ASP, C# and VB.NET

I now work as Senior Microsoft Dynamics AX and .Net programmer, and have a number of projects in various states of progress to work on in the spare time...

Comments and Discussions

 
GeneralMy vote of 5 Pin
HerbF14-Jan-20 10:48
HerbF14-Jan-20 10:48 
QuestionIf your selected item does not draw... Pin
Member 1234981330-Nov-16 13:10
Member 1234981330-Nov-16 13:10 
AnswerRe: If your selected item does not draw... Pin
Johnny J.30-Nov-16 21:02
professionalJohnny J.30-Nov-16 21:02 
QuestionMy Vote Pin
Evgeni Primakov12-Nov-14 13:43
Evgeni Primakov12-Nov-14 13:43 
AnswerRe: My Vote Pin
Johnny J.12-Nov-14 22:29
professionalJohnny J.12-Nov-14 22:29 
GeneralMy vote of 1 Pin
Baron Mamurny5-Jul-13 0:12
Baron Mamurny5-Jul-13 0:12 
GeneralRe: My vote of 1 Pin
Johnny J.5-Jul-13 0:16
professionalJohnny J.5-Jul-13 0:16 
GeneralRe: My vote of 1 Pin
Baron Mamurny5-Jul-13 0:18
Baron Mamurny5-Jul-13 0:18 
GeneralRe: My vote of 1 Pin
Johnny J.5-Jul-13 0:33
professionalJohnny J.5-Jul-13 0:33 
SuggestionSuggested change Pin
TnTinMn22-May-13 11:53
TnTinMn22-May-13 11:53 
GeneralRe: Suggested change Pin
Johnny J.22-May-13 20:55
professionalJohnny J.22-May-13 20:55 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.