We help IT Professionals succeed at work.

Changing Colors of individual Items in ComboBox in VS2005 / C#

dfins
dfins asked
on
9,473 Views
Last Modified: 2010-04-21
Hey guys,
 
     I've got a SQL query that's dumping a bunch of data to me. As I parse through the records, I've got a list of items that I would like to distinguish between one another. For example, some items I would like to be red, others I would like to be green.

I've looked all over the internet, and the best examples I've found don't do anything else other than showing me how to change the colors based on if all of the data was pre-populated into an array, and that the text matched up with color names, for example.

This won't help me because I will only know what colors I want that individual item to be at the moment that I do my "comboBox.Items.Add" command.


This is the best code that I can find, but as you can see, it's event driven, which doesn't help me much because I have no way of passing pertinant "CASE / SWITCH" information to this event driven procedure. So it really doesn't help me at all...

Any idea how I can do this?



private void Form1_Load(object sender, System.EventArgs e)  
{  
   comboBox2.Items.Add("Item 1");  
   comboBox2.Items.Add("Item 2");  
   comboBox2.Items.Add("Item 3");  
}  
 
private void comboBox2_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e)  
{  
Graphics g = e.Graphics ;  
 
if ( e.Index == 1 )    
{  
   SolidBrush b = (SolidBrush)new SolidBrush(Color.Black);  
   e.Graphics.DrawString(b.Color.Name, new Font("Veranda", 12, FontStyle.Bold), new SolidBrush(Color.Red), e.Bounds);  
   e.DrawFocusRectangle();  
}  
 
if (e.Index == 2)  
{  
   SolidBrush b = (SolidBrush)new SolidBrush(Color.Red);  
   e.Graphics.DrawString(b.Color.Name, new Font("Veranda", 12, FontStyle.Bold), new SolidBrush(Color.Yellow), e.Bounds);  
   e.DrawFocusRectangle();  
}  
 
if (e.Index == 3)  
{  
   SolidBrush b = (SolidBrush)new SolidBrush(Color.Firebrick);  
   e.Graphics.DrawString(b.Color.Name, new Font("Veranda", 12, FontStyle.Bold), new SolidBrush(Color.Silver), e.Bounds);  
   e.DrawFocusRectangle();  
}  
Comment
Watch Question

Jaime OlivaresSoftware Architect
CERTIFIED EXPERT
Top Expert 2008

Commented:
Which criteria do you want to evaluate?
How are you filling your data into your control?

Author

Commented:
Well, the criteria of what I'm evaluating isn't of any signifigance, at least to this example, but basically... for each record in my query, I run a check, like for example, if this one field... if the Boolean is set to TRUE, then I want the text that I put into my ComboBox for that item to be RED, for example, otherwise I want it to be BLACK.

I'm filing it in right now by doing ComboBox.Items.Add("current record goes here");
Jaime OlivaresSoftware Architect
CERTIFIED EXPERT
Top Expert 2008

Commented:
Create a class or struct as:
public class ComboItem
{
     public string str;
     public Color color;

     public ComboItem(string _str, Color _color)
     {
          str = _str;
          color = _color;
     }
     public override string ToString()
     {
          return this.str;
     }
}

Then evaluate your criteria as you want and determine some color in a variable. Finally add the item to the combo as:
yourCombo.Items.Add(new ComboItem(yourStr, yourColor));
Everything should work as usual, but now you can know the color when painting:
private void comboBox2_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e)  
{
   SolidBrush b = (SolidBrush)new SolidBrush((e.Item as ComboItem).color);  
   e.Graphics.DrawString(e.Item.ToString(), controlFont, b, e.Bounds);  
   e.DrawFocusRectangle();    
}

notice there is a "controlFont" variable. Define it as a form's member as:
public Font controlFont = new Font("Veranda", 12, FontStyle.Bold)
 so you don't have to create it every time you need it.

Author

Commented:
Thanks Jamie, this is awesome... so close... the only problem is that I get an error:

Error      'System.Windows.Forms.DrawItemEventArgs' does not contain a definition for 'Item'

Any idea what I should use instead for item? I got pretty far awhile back, and then ran into this same problem.

Thank you for helping me!
Jaime OlivaresSoftware Architect
CERTIFIED EXPERT
Top Expert 2008

Commented:
Sorry, writing from my memory, replace the drawitem method with
private void comboBox2_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e)  
{
   ComboItem item = comboBox2.Items[e.Index] as ComboItem;
   SolidBrush b = (SolidBrush)new SolidBrush(item.color);  
   e.Graphics.DrawString(item.str, controlFont, b, e.Bounds);  
   e.DrawFocusRectangle();    
}

Author

Commented:
Thank you so much! I'm ALMOST there... the ONLY problem Ihave is that I get this error:

InvalidArgument=Value of '-1' is not valid for 'index'.
Parameter name: index

Any idea? I don't know why it would be set to -1? I add the items on Form-Load...
Jaime OlivaresSoftware Architect
CERTIFIED EXPERT
Top Expert 2008

Commented:
It is unrelated to my proposal. I guess the -1 comes from some code where you are trying to use your color criteria.
-1 means that an IndexOf() method didn't find an expected string. Maybe you can post some code around,.
 

Author

Commented:
Thanks Jaime, below is actually the entire application.

I built a small application to test the code before I moved it to my actual application. I get the same error:


VS2005 / C#


 
 
-----------------------------------------------------------------------------------------------------------------
 

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
namespace MyComboBox
{
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.ComboBox comboBox2;
private System.ComponentModel.Container components = null;
public Font controlFont = new Font("Veranda", 12, FontStyle.Bold);
 
 
public Form1()
{
InitializeComponent();
}
 
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
 
private void InitializeComponent()
{
this.comboBox2 = new System.Windows.Forms.ComboBox();
this.SuspendLayout();
//
// comboBox2
//
this.comboBox2.BackColor = System.Drawing.SystemColors.ActiveCaptionText;
this.comboBox2.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed;
this.comboBox2.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.comboBox2.ItemHeight = 20;
this.comboBox2.Items.AddRange(new object[] {
"Please select a player..."});
this.comboBox2.Location = new System.Drawing.Point(12, 12);
this.comboBox2.Name = "comboBox2";
this.comboBox2.Size = new System.Drawing.Size(288, 26);
this.comboBox2.TabIndex = 0;
this.comboBox2.DrawItem += new System.Windows.Forms.DrawItemEventHandler(this.comboBox2_DrawItem);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(312, 157);
this.Controls.Add(this.comboBox2);
this.Name = "Form1";
this.Text = "OwnerDraw ComboBox";
this.Load += new System.EventHandler(this.Form1_Load);
this.ResumeLayout(false);
}
static void Main()
{
Application.Run(new Form1());
}
 
 
 
private void Form1_Load(object sender, System.EventArgs e)
{
comboBox2.Items.Add(new ComboItem("Item 1", Color.Red));
comboBox2.Items.Add(new ComboItem("Item 1", Color.Red));
comboBox2.Items.Add(new ComboItem("Item 1", Color.Red));
comboBox2.Items.Add(new ComboItem("Item 1", Color.Red));
}
private void comboBox2_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e)
{
ComboItem item = comboBox2.Items[e.Index] as ComboItem;
SolidBrush b = (SolidBrush)new SolidBrush(item.color);
e.Graphics.DrawString(item.str, controlFont, b, e.Bounds);
e.DrawFocusRectangle();
}
}
public class ComboItem
{
public string str;
public Color color;
public ComboItem(string _str, Color _color)
{
str = _str;
color = _color;
}
public override string ToString()
{
return this.str;
}
}
 
}
Software Architect
CERTIFIED EXPERT
Top Expert 2008
Commented:
This one is on us!
(Get your first solution completely free - no credit card required)
UNLOCK SOLUTION

Author

Commented:
I made a couple of tweaks to it, but that was the answer, and now it works!!!!
 
 
See code:
 

static void Main()
{
Application.Run(new Form1());
}
 
 
 
private void Form1_Load(object sender, System.EventArgs e)
{
comboBox2.Items.Add(new ComboItem("Item 1", Color.Red));
comboBox2.Items.Add(new ComboItem("Item 1", Color.Red));
comboBox2.Items.Add(new ComboItem("Item 1", Color.Red));
comboBox2.Items.Add(new ComboItem("Item 1", Color.Red));
}
private void comboBox2_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e)
{
if (e.Index > 0)
{
ComboItem item = comboBox2.Items[e.Index] as ComboItem;
SolidBrush b = (SolidBrush)new SolidBrush(item.color);
e.Graphics.DrawString(item.str, controlFont, b, e.Bounds);
e.DrawFocusRectangle();
}
}
}
public class ComboItem
{
public string str;
public Color color;
public ComboItem(string _str, Color _color)
{
str = _str;
color = _color;
}
public override string ToString()
{
return this.str;
}
}  

Author

Commented:
See final code in last post.
Jaime OlivaresSoftware Architect
CERTIFIED EXPERT
Top Expert 2008

Commented:
about this:
>>if (e.Index > 0)

index could be 0, so I guess it should be:
if (e.Index >= 0)
 

Author

Commented:
Hah... thanks! You're right!!!
By the way, I really appreciate the help!!! You saved me tons of hours of anguish...

Gain unlimited access to on-demand training courses with an Experts Exchange subscription.

Get Access
Why Experts Exchange?

Experts Exchange always has the answer, or at the least points me in the correct direction! It is like having another employee that is extremely experienced.

Jim Murphy
Programmer at Smart IT Solutions

When asked, what has been your best career decision?

Deciding to stick with EE.

Mohamed Asif
Technical Department Head

Being involved with EE helped me to grow personally and professionally.

Carl Webster
CTP, Sr Infrastructure Consultant
Empower Your Career
Did You Know?

We've partnered with two important charities to provide clean water and computer science education to those who need it most. READ MORE

Ask ANY Question

Connect with Certified Experts to gain insight and support on specific technology challenges including:

  • Troubleshooting
  • Research
  • Professional Opinions
Unlock the solution to this question.
Join our community and discover your potential

Experts Exchange is the only place where you can interact directly with leading experts in the technology field. Become a member today and access the collective knowledge of thousands of technology experts.

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.