dfins
asked on
Changing Colors of individual Items in ComboBox in VS2005 / C#
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.DrawI temEventAr gs e)
{
Graphics g = e.Graphics ;
if ( e.Index == 1 )
{
SolidBrush b = (SolidBrush)new SolidBrush(Color.Black);
e.Graphics.DrawString(b.Co lor.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.Co lor.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.Co lor.Name, new Font("Veranda", 12, FontStyle.Bold), new SolidBrush(Color.Silver), e.Bounds);
e.DrawFocusRectangle();
}
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.DrawI
{
Graphics g = e.Graphics ;
if ( e.Index == 1 )
{
SolidBrush b = (SolidBrush)new SolidBrush(Color.Black);
e.Graphics.DrawString(b.Co
e.DrawFocusRectangle();
}
if (e.Index == 2)
{
SolidBrush b = (SolidBrush)new SolidBrush(Color.Red);
e.Graphics.DrawString(b.Co
e.DrawFocusRectangle();
}
if (e.Index == 3)
{
SolidBrush b = (SolidBrush)new SolidBrush(Color.Firebrick
e.Graphics.DrawString(b.Co
e.DrawFocusRectangle();
}
ASKER
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("curren t record goes here");
I'm filing it in right now by doing ComboBox.Items.Add("curren
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.DrawI temEventAr gs e)
{
SolidBrush b = (SolidBrush)new SolidBrush((e.Item as ComboItem).color);
e.Graphics.DrawString(e.It em.ToStrin g(), 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.
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.DrawI
{
SolidBrush b = (SolidBrush)new SolidBrush((e.Item as ComboItem).color);
e.Graphics.DrawString(e.It
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.
ASKER
Thanks Jamie, this is awesome... so close... the only problem is that I get an error:
Error 'System.Windows.Forms.Draw ItemEventA rgs' 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!
Error 'System.Windows.Forms.Draw
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!
Sorry, writing from my memory, replace the drawitem method with
private void comboBox2_DrawItem(object sender, System.Windows.Forms.DrawI temEventAr gs 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();
}
private void comboBox2_DrawItem(object sender, System.Windows.Forms.DrawI
{
ComboItem item = comboBox2.Items[e.Index] as ComboItem;
SolidBrush b = (SolidBrush)new SolidBrush(item.color);
e.Graphics.DrawString(item
e.DrawFocusRectangle();
}
ASKER
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...
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...
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,.
-1 means that an IndexOf() method didn't find an expected string. Maybe you can post some code around,.
ASKER
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.Combo Box comboBox2;
private System.ComponentModel.Cont ainer 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.Combo Box();
this.SuspendLayout();
//
// comboBox2
//
this.comboBox2.BackColor = System.Drawing.SystemColor s.ActiveCa ptionText;
this.comboBox2.DrawMode = System.Windows.Forms.DrawM ode.OwnerD rawFixed;
this.comboBox2.DropDownSty le = System.Windows.Forms.Combo BoxStyle.D ropDownLis t;
this.comboBox2.ItemHeight = 20;
this.comboBox2.Items.AddRa nge(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.DrawI temEventHa ndler(this .comboBox2 _DrawItem) ;
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(312, 157);
this.Controls.Add(this.com boBox2);
this.Name = "Form1";
this.Text = "OwnerDraw ComboBox";
this.Load += new System.EventHandler(this.F orm1_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.DrawI temEventAr gs 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;
}
}
}
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.Combo
private System.ComponentModel.Cont
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.Combo
this.SuspendLayout();
//
// comboBox2
//
this.comboBox2.BackColor = System.Drawing.SystemColor
this.comboBox2.DrawMode = System.Windows.Forms.DrawM
this.comboBox2.DropDownSty
this.comboBox2.ItemHeight = 20;
this.comboBox2.Items.AddRa
"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.DrawI
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(312, 157);
this.Controls.Add(this.com
this.Name = "Form1";
this.Text = "OwnerDraw ComboBox";
this.Load += new System.EventHandler(this.F
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.DrawI
{
ComboItem item = comboBox2.Items[e.Index] as ComboItem;
SolidBrush b = (SolidBrush)new SolidBrush(item.color);
e.Graphics.DrawString(item
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;
}
}
}
ASKER CERTIFIED SOLUTION
membership
Create a free account to see this answer
Signing up is free and takes 30 seconds. No credit card required.
ASKER
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.DrawI temEventAr gs 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;
}
}
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.DrawI
{
if (e.Index > 0)
{
ComboItem item = comboBox2.Items[e.Index] as ComboItem;
SolidBrush b = (SolidBrush)new SolidBrush(item.color);
e.Graphics.DrawString(item
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;
}
}
ASKER
See final code in last post.
about this:
>>if (e.Index > 0)
index could be 0, so I guess it should be:
if (e.Index >= 0)
>>if (e.Index > 0)
index could be 0, so I guess it should be:
if (e.Index >= 0)
ASKER
Hah... thanks! You're right!!!
By the way, I really appreciate the help!!! You saved me tons of hours of anguish...
By the way, I really appreciate the help!!! You saved me tons of hours of anguish...
How are you filling your data into your control?