37
votes

I am trying to change the background color of some rows in a ListBox. I have two lists that one has names and is displayed in a ListBox. The second list has some similar values as the first List. When clicking a button, I want to search the ListBox and the second List, and change the color of the ListBox for those values that appear in the List. My search in the ListBox is as follows:

for (int i = 0; i < listBox1.Items.Count; i++)
{
    for (int j = 0; j < students.Count; j++)
    {
        if (listBox1.Items[i].ToString().Contains(students[j].ToString()))
        {
        }
    }
}

But I don't know which method to use in order to change the appearance of a ListBox row. Can anybody help me?

**EDIT: **

HI I wrote my code as follows:

private void ListBox1_DrawItem(object sender, DrawItemEventArgs e)
{
    e.DrawBackground();
    Graphics g = e.Graphics;
    Brush myBrush = Brushes.Black;
    Brush myBrush2 = Brushes.Red;
    g.FillRectangle(new SolidBrush(Color.Silver), e.Bounds);
    e.Graphics.DrawString(listBox1.Items[e.Index].ToString(), e.Font, myBrush, e.Bounds, StringFormat.GenericDefault);
    for (int i = 0; i < listBox1.Items.Count; i++)
    {
        for (int j = 0; j < existingStudents.Count; j++)
        {
            if (listBox1.Items[i].ToString().Contains(existingStudents[j]))
            {
                e.Graphics.DrawString(listBox1.Items[i].ToString(),
                e.Font, myBrush2, e.Bounds, StringFormat.GenericDefault);
            }
        }
    }
    e.DrawFocusRectangle();
}

Now it draws my List in the ListBox, but when I click the button first, it shows in red only the students that are in the List and when I click on the ListBox it draws all the elements. I want that it will show all the elements , and when I click the button it will show all the elements and the element found in the List in red. Where is my mistake?

7
Draw it yourself using OwnerDraw: c-sharpcorner.com/UploadFile/sahuja/…Michael Todd
After your update: apparently you're not getting what the previous answerers below showed you. The DrawItem method draws one item, not multiple items. You're going to need to handle each item as needed, and not use a for loop to process all items. Take a look at Thomas Levesque's or Justin's answer for good examples.Michael Todd
But if I want to show two record in listbox? I could not do this? 2 record of 5 will change color ,others will be same color.Ercan
What is your condition for one record to change color and the others to show the same color? How could you programmatically tell the difference?Michael Todd

7 Answers

37
votes

I find solution that instead of using ListBox I used ListView.It allows to change list items BackColor.

private void listView1_Refresh()
{
    for (int i = 0; i < listView1.Items.Count; i++)
    {
        listView1.Items[i].BackColor = Color.Red;
        for (int j = 0; j < existingStudents.Count; j++)
        {
            if (listView1.Items[i].ToString().Contains(existingStudents[j]))
            {
                listView1.Items[i].BackColor = Color.Green;
            }
        }
    }
}
25
votes

You will need to draw the item yourself. Change the DrawMode to OwnerDrawFixed and handle the DrawItem event.

/// <summary>
/// Handles the DrawItem event of the listBox1 control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="System.Windows.Forms.DrawItemEventArgs"/> instance containing the event data.</param>
private void listBox1_DrawItem( object sender, DrawItemEventArgs e )
{
   e.DrawBackground();
   Graphics g = e.Graphics;

    // draw the background color you want
    // mine is set to olive, change it to whatever you want
    g.FillRectangle( new SolidBrush( Color.Olive), e.Bounds );

    // draw the text of the list item, not doing this will only show
    // the background color
    // you will need to get the text of item to display
    g.DrawString( THE_LIST_ITEM_TEXT , e.Font, new SolidBrush( e.ForeColor ), new PointF( e.Bounds.X, e.Bounds.Y) );

    e.DrawFocusRectangle();
}
17
votes

First use this Namespace:

using System.Drawing;

Add this anywhere on your form:

listBox.DrawMode = DrawMode.OwnerDrawFixed;
listBox.DrawItem += listBox_DrawItem;

Here is the Event Handler:

private void listBox_DrawItem(object sender, DrawItemEventArgs e)
{
     e.DrawBackground();

     Graphics g = e.Graphics;
     g.FillRectangle(new SolidBrush(Color.White), e.Bounds);
     ListBox lb = (ListBox)sender;
     g.DrawString(lb.Items[e.Index].ToString(), e.Font, new SolidBrush(Color.Black), new PointF(e.Bounds.X, e.Bounds.Y));

     e.DrawFocusRectangle();
}
3
votes

I think you have to draw the listitems yourself to achieve this.

Here's a post with the same kind of question.

1
votes

Once you've added your listbox item to your form, change DrawMode with OwnerDrawFixed option from the Properties panel. If you forget to do this, none of the codes below will work. Then click DrawItem event from the Events area.

private void listBox1_DrawItem(object sender, DrawItemEventArgs e)
{
   // 1. Get the item
   string selectedItem = listBox1.Items[e.Index].ToString();
                    
   // 2. Choose font 
   Font font = new Font("Arial", 12);
        
   // 3. Choose colour
   SolidBrush solidBrush = new SolidBrush(Color.Red);
        
   // 4. Get bounds
   int left = e.Bounds.Left;
   int top = e.Bounds.Top;
                    
   // 5. Use Draw the background within the bounds
   e.DrawBackground();
        
   // 6. Colorize listbox items
   e.Graphics.DrawString(selectedItem, font, solidBrush, left, top);
}
0
votes

I find the solution for listbox items' background to yellow. I tried the following solution to achieve the output.

 for (int i = 0; i < lstEquipmentItem.Items.Count; i++)
                {
                    if ((bool)ds.Tables[0].Rows[i]["Valid_Equipment"] == false)
                    {
                        lblTKMWarning.Text = "Invalid Equipment & Serial Numbers are highlited.";
                        lblTKMWarning.ForeColor = System.Drawing.Color.Red;
                        lstEquipmentItem.Items[i].Attributes.Add("style", "background-color:Yellow");
                        Count++;
                    }

                }
-6
votes

How about

      MyLB is a listbox

        Label ll = new Label();
        ll.Width = MyLB.Width;
        ll.Content = ss;
        if(///<some condition>///)
            ll.Background = Brushes.LightGreen;
        else
            ll.Background = Brushes.LightPink;
        MyLB.Items.Add(ll);