Android Addicted Apps Creator

May 10, 2009

Combo Box with colors and text – Part I

Filed under: Windows forms — alinberce @ 17:46
Tags: ,

First things, first: A BIG BIG THANK YOU, for my friend Claudiu which always gives me the right solution when I’m stuck and has the nonhuman patience to teach me . Respect.

I’ve seen in some applications pretty nice combo boxes that contained beside the text some graphics too. So, I thought, why not make one myself? It can’t be that hard… no? Well, not very hard but, very interesting. In order to achieve this, I will take a simple example from the qPlanner application: each task has a certain priority, let’s say “High”, “Medium”, “Low”. Each priority type has a specific color: Red, Orange, Green. The combo box control will have to be able to display a small square with the color and the text of the priority.

Get ready, take a big breath, and let’s try to do it together.

First of all let’s create a new project, of type Window forms application. I will name it ColoredCombo. Open Form1 and add to it a ComboBox, name it cboPriority and set it’s DropDownStyle to DropDownList and it’s DrawMode to OwnerDrawFixed.

image

Things become a little more interesting. The DataSource of the cboPriority will be a List<> containing the PriorityObjects we choose to. This may sound weird now, but in a few lines of code you will get the idea. Add a new item to the project of type class and name it PriorityObject.cs. Add the following code into it:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace ColoredCombo
{
    public class PriorityObject
    {
        public string Name { get; set; }
        public Color Color { get; set; }

        public PriorityObject(string name, Color color)
        {
            Name = name;
            Color = color;
        }
    }
}

Each object of type PriorityObject will have a Name  and a Color. To have a list of these object we will add a new class to the project, named PriorityCollections.cs

using System.Collections.Generic;
using System.Drawing;

namespace ColoredCombo
{
    public class PriorityCollections
    {
        public static List<PriorityObject> GetPriorities() 
        {
            List<PriorityObject> lst = new List<PriorityObject>();
            
            lst.Add(new PriorityObject( "High", Color.Red));
            lst.Add(new PriorityObject( "Medium", Color.Orange));
            lst.Add(new PriorityObject( "Low", Color.YellowGreen));
            
            return lst;
        }
    }
}

This being done, we will proceed in completing the combo box master piece. Go back to Form1, right click on cboPriority and choose Properties. On Properties window press the Events button (you know… the little one with the lightning on it) and add a new event for Draw item (cboPriority_DrawItem).

In this event, using GDI+, we will draw each combo box item manually. Each item will be composed from a small square which will be filled with the right color and a text contain the priority. But what is GDI+ ? You may ask… Microsoft Windows GDI+ is a class-based API that enables applications to use graphics and formatted text on both the video display and the printer. Applications based on the Microsoft Win32 API do not access graphics hardware directly. Instead, GDI+ interacts with device drivers on behalf of applications.

First we need to give a DataSource to the ComboBox. For this I will make a simple method and call it in form load.

 private void GetPriorityList()
        {
            lstPriority = PriorityCollections.GetPriorities();
            cboPriority.DataSource = lstPriority;
            cboPriority.ValueMember = "Color";
            cboPriority.DisplayMember = "Name";
        }    

where  lstPriority is declared as a private variable;

Run the project and see the results. It should look like this:

image Nothing spectacular until now. Prepare yourself to do some drawing. In the cboPriority_DrawItem created before add the next code:

private void cboPriority_DrawItem(object sender, DrawItemEventArgs e)
        {
            e.DrawBackground();
            if (e.Index >= 0)
            {
                Color clr = lstPriority[e.Index].Color;
                using (Brush brush = new SolidBrush(clr))
                {
                    e.Graphics.FillRectangle(brush, e.Bounds.X, e.Bounds.Y, 14, 14);
                }

                using (Brush brush = new SolidBrush(e.ForeColor))
                {
                    e.Graphics.DrawString(lstPriority[e.Index].Name.ToString(), e.Font, brush, e.Bounds.Left + 16, e.Bounds.Top);
                }
                e.DrawFocusRectangle();

            }
        }

As you can seem in clr variable I take the current drawn item Color property. Creating a solid brush with this color, I draw a rectangle of 14×14 pixels. I also create a string with current item Name property and I draw it beside the created rectangle (e.bounds.Left+16).

Run the project and prepare yourself to be amazed:

image

Advertisements

Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: