Background Color of a Listbox Item (Windows Forms)

Background color of a ListBox item (Windows Forms)

Probably the only way to accomplish that is to draw the items yourself.

Set the DrawMode to OwnerDrawFixed and code something like this on the DrawItem event:

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

g.FillRectangle(new SolidBrush(Color.Silver), e.Bounds);

// Print text

e.DrawFocusRectangle();
}

The second option would be using a ListView, although they have an other way of implementations (not really data bound, but more flexible in way of columns).

How to change ListBox selection background color?

You must override the Drawitem event and set the DrawMode property to DrawMode.OwnerDrawFixed

check this sample

private void listBox1_DrawItem(object sender, DrawItemEventArgs e)
{
if (e.Index<0) return;
//if the item state is selected them change the back color
if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)
e = new DrawItemEventArgs(e.Graphics,
e.Font,
e.Bounds,
e.Index,
e.State ^ DrawItemState.Selected,
e.ForeColor,
Color.Yellow);//Choose the color

// Draw the background of the ListBox control for each item.
e.DrawBackground();
// Draw the current item text
e.Graphics.DrawString(listBox1.Items[e.Index].ToString(),e.Font, Brushes.Black, e.Bounds, StringFormat.GenericDefault);
// If the ListBox has focus, draw a focus rectangle around the selected item.
e.DrawFocusRectangle();
}

alt text

How to change the background color of a ListBox Item when hovering?

As the ListBox does not provide the MouseEnterItem and MouseHoverItem Events, it is necessary to code this functionality yourself, tracking the coordinates of the mouse to determine which item the mouse is over.

The following question is very similar, aimed at showing a tooltip for each item when hovered over. Michael Lang's answer is a very good workaround and should be adaptable for your purposes:

How can I set different Tooltip text for each item in a listbox?

C# : change listbox items color

Assuming WinForms, this is what I would do:

Start by making a class to contain the item to add to the listbox.

public class MyListBoxItem {
public MyListBoxItem(Color c, string m) {
ItemColor = c;
Message = m;
}
public Color ItemColor { get; set; }
public string Message { get; set; }
}

Add items to your listbox using this code:

listBox1.Items.Add(new MyListBoxItem(Colors.Green, "Validated data successfully"));
listBox1.Items.Add(new MyListBoxItem(Colors.Red, "Failed to validate data"));

In the properties of the ListBox, set DrawMode to OwnerDrawFixed, and create an event handler for the DrawItem event. This allows you to draw each item however you wish.

In the DrawItem Event:

private void listBox1_DrawItem(object sender, DrawItemEventArgs e)
{
MyListBoxItem item = listBox1.Items[e.Index] as MyListBoxItem; // Get the current item and cast it to MyListBoxItem
if (item != null)
{
e.Graphics.DrawString( // Draw the appropriate text in the ListBox
item.Message, // The message linked to the item
listBox1.Font, // Take the font from the listbox
new SolidBrush(item.ItemColor), // Set the color
0, // X pixel coordinate
e.Index * listBox1.ItemHeight // Y pixel coordinate. Multiply the index by the ItemHeight defined in the listbox.
);
}
else
{
// The item isn't a MyListBoxItem, do something about it
}
}

There are a few limitations - the main one being that you'd need to write your own click handler and redraw appropriate items to make them appear selected, since Windows won't do that in OwnerDraw mode. However, if this is just intended to be a log of things happening in your application, you may not care about items appearing selectable.

To scroll to the last item try

listBox1.TopIndex = listBox1.Items.Count - 1;

C# : changing listbox row color?

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;
}
}
}
}

Winforms - Listbox item hover and select color

You can create your own listbox deriving from the original one. Once the new list is compiled for the first time, it will appear in the toolbox, so that you can drag and drop it onto your forms. Or you can change the type of existing listboxes to ListBoxEx in the Form.designer.cs manually.

public class ListBoxEx : ListBox
{
public ListBoxEx()
{
DrawMode = DrawMode.OwnerDrawFixed;
DoubleBuffered = true; // Eliminates flicker (optional).
}

private int _hotTrackedIndex = -1;
private int HotTrackedIndex
{
get => _hotTrackedIndex;
set {
if (value != _hotTrackedIndex) {
if (_hotTrackedIndex >= 0 && _hotTrackedIndex < Items.Count) {
Invalidate(GetItemRectangle(_hotTrackedIndex));
}
_hotTrackedIndex = value;
if (_hotTrackedIndex >= 0) {
Invalidate(GetItemRectangle(_hotTrackedIndex));
}
}
}
}

protected override void OnDrawItem(DrawItemEventArgs e)
{
var borderRect = e.Bounds;
borderRect.Width--;
borderRect.Height--;
if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) {
if (Focused) {
e.Graphics.FillRectangle(Brushes.Teal, e.Bounds);
e.Graphics.DrawRectangle(Pens.LightSkyBlue, borderRect);
} else {
e.Graphics.FillRectangle(Brushes.DimGray, e.Bounds);
e.Graphics.DrawRectangle(Pens.White, borderRect);
}
} else if (e.Index == HotTrackedIndex) {
e.Graphics.FillRectangle(Brushes.DarkSlateGray, e.Bounds);
e.Graphics.DrawRectangle(Pens.DarkCyan, borderRect);
} else {
e.DrawBackground();
}
if (Items[e.Index] != null) {
e.Graphics.DrawString(Items[e.Index].ToString(), e.Font, Brushes.White, 6, e.Bounds.Top, StringFormat.GenericTypographic);
}
}

protected override void OnMouseLeave(EventArgs e)
{
HotTrackedIndex = -1;
base.OnMouseLeave(e);
}

protected override void OnMouseMove(MouseEventArgs e)
{
HotTrackedIndex = IndexFromPoint(e.Location);
base.OnMouseMove(e);
}

protected override void OnGotFocus(EventArgs e)
{
if (SelectedIndex >= 0) {
RefreshItem(SelectedIndex);
}
base.OnGotFocus(e);
}

protected override void OnLostFocus(EventArgs e)
{
if (SelectedIndex >= 0) {
RefreshItem(SelectedIndex);
}
base.OnLostFocus(e);
}
}

We change the appearance of the listbox by overriding OnDrawItem. in the constructor, we set DrawMode = DrawMode.OwnerDrawFixed; to enable owner drawing.

We must consider selected items and hot tracked items, i.e., items the mouse moves over. If the item to be drawn is the selected one, we further differentiate between the cases where the listbox has the focus or not.

FillRectangle draws the background. DrawRectangle draws the border. Note that the border rectangle must be smaller by one pixel than the e.Bounds rectangle, otherwise the right and bottom borders will not be drawn.

If the current item is not selected, we test to see whether it is hot tracked. If it is, we draw in different colors. Otherwise we draw the default background with e.DrawBackground();.

Then we draw the text over the background with DrawString.


For all this to work, we also must invalidate regions of the listbox where the colors are changing. We detect changes in hot tracking in OnMouseMove and OnMouseLeave. There we set the HotTrackedIndex. This is a property which triggers drawing when necessary.

In OnGotFocus and OnLostFocus we refresh the selected item to change its color depending on the focused state.


My colors do not match your images, but you can easily tweak them. If you need to create Brushes and Pens in non-standard colors, then either create them as static and read-only or then don't forget to dispose them.

private static readonly Brush HotTrackBrush = new SolidBrush(new Color(123, 45, 67));
private static readonly Pen HotTrackPen = new Pen(new Color(234, 56, 78));

An improved version of this listbox could expose the different selection and hot tracking colors as properties, so that you could easily change them in the properties window. (Properties automatically appear there.)



Related Topics



Leave a reply



Submit