I'm using this code to colour individual items in a listbox, but the problem i am having is it colours all previous items with the new colour. How can i colour each induvidual item without this happening?

Here is the code I'm using: (_colour is a global int)

private void debugconsole_DrawItem(object sender, DrawItemEventArgs e)
{
	try
	{
		e.DrawBackground();
		Brush myBrush = Brushes.Black;
		switch (_colour)
		{
			case 0:
				myBrush = Brushes.Green;
				break;
			case 1:
				myBrush = Brushes.Orange;
				break;
			case 2:
				myBrush = Brushes.Red;
				break;
			case 3:
				myBrush = Brushes.Gray;
				break;
		}
		e.Graphics.DrawString(((ListBox) sender).Items[e.Index].ToString(),
							  e.Font, myBrush, e.Bounds, StringFormat.GenericDefault);
		e.DrawFocusRectangle();
	}
	catch
	{
		MessageBox.Show("Error");
	}
}

Recommended Answers

All 14 Replies

Hi,

Create a new:

System.Web.UI.WebControls.ListItem

for each item and set its color as you want, or you can of course set its cssclass to call different classes and there set the colors that you want

Use

switch (_colour%4)

dont mess up with listbox, use listview instead. you have more control over the items. listbox items are just ordinary strings and you cant play around with them. try to debug it, if you dont hit that portion of code then you should modify the drawmode from the properties of the listbox to OwnerDrawFixed.

@adatapost what does %4 do?

@serkan sendur so with listviews, will i need to use a different method to draw each part? or will it be almost exactly the same code as above?

listviewitem has a foregroundColor and backgroundColor properties, so you can directly set them while iterating with foreach statement.

foreach(ListViewItem lvi in listView1.Items)
			{
								// add your if statement here to specify condition
		lvi.ForeColor = Color.Red;
				
			}

% - modulo operator
1%4 = 1
2%4 = 2
3%4 = 3
4%4 = 0
5%4 = 1
....

Serkan suggestion is better option for you.

private void debugconsole_DrawItem(object sender, DrawItemEventArgs e)
{
	try
	{
		e.DrawBackground();
		Brush myBrush = Brushes.Black;
		switch (_colour%4)
		{
			case 0:
				myBrush = Brushes.Green;
				break;
			case 1:
				myBrush = Brushes.Orange;
				break;
			case 2:
				myBrush = Brushes.Red;
				break;
			case 3:
				myBrush = Brushes.Gray;
				break;
		}
                               _colour++;
		e.Graphics.DrawString(((ListBox) sender).Items[e.Index].ToString(),
							  e.Font, myBrush, e.Bounds, StringFormat.GenericDefault);
		e.DrawFocusRectangle();
	}
	catch
	{
		MessageBox.Show("Error");
	}
}

OK, first, thanks for all the help!
I switched to listview and everything is going smooth.
I also didn't include the modulo because it's not needed in my program (and would interfere with when i don't want to colour it)

I also found this way easier, here's my updated code:
(I'm using it like a Log of activities, msg and argcolor are arguments for the method)

//Set the time
string hour, min, sec;
if (DateTime.Now.Hour < 10)
{
    hour = 0 + Convert.ToString(DateTime.Now.Hour);
}
else hour = Convert.ToString(DateTime.Now.Hour);
if (DateTime.Now.Minute < 10)
{
    min = 0 + Convert.ToString(DateTime.Now.Minute);
}
else min = Convert.ToString(DateTime.Now.Minute);
if (DateTime.Now.Second < 10)
{
    sec = 0 + Convert.ToString(DateTime.Now.Second);
}
else sec = Convert.ToString(DateTime.Now.Second);

//Add the item
debugconsole.Items.Add(string.Format("[{0}:{1}:{2}] {3}", hour, min, sec, msg));

//Find the last item added, ready for the next step
int lastitem = debugconsole.Items.Count - 1;
//Now set the colour
switch (argcolour)
{
    case 0:
        debugconsole.Items[lastitem].ForeColor = Color.Green;
        break;
    case 1:
        debugconsole.Items[lastitem].ForeColor = Color.Orange;
        break;
    case 2:
        debugconsole.Items[lastitem].ForeColor = Color.Red;
        break;
    case 3:
        debugconsole.Items[lastitem].ForeColor = Color.Gray;
        break;
}

//This selects the last line, then unselects it, so that console scrolls to the bottom
debugconsole.Items[lastitem].Selected = true;
debugconsole.Items[lastitem].Selected = false;

i just replaced the switch/case with debugconsole.Items[lastitem].ForeColor = colour; and changed the argument to a Color instead of an int.

is there a way to simplify the code i used from lines 3 to 17? last question :P

Perhaps something like this:

string str = string.Empty;
DateTime T = DateTime.Now;
str = T.ToString("hh:MM:ss");
MessageBox.Show(str);

i just replaced the switch/case with debugconsole.Items[lastitem].ForeColor = colour; and changed the argument to a Color instead of an int.

is there a way to simplify the code i used from lines 3 to 17? last question :P

Of course there is use:

String.Format("{0:T}", DateTime.Now);

Hopes that what you want

String.Format("{0:T}", DateTime.Now);

thanks, just what i needed!

thanks, just what i needed!

Mark the thread as solved

Mark the thread as solved

the thread was already marked as solved before even your previous post.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.