I am setting the ForeColor of all items in my ListView to a different color, but this get\'s overrided when the item is selected (changes to Black again; changes back to cus
Enable your ListView OwnerDraw
mode, then subscribe its DrawItem
and DrawColumnHeader
events.
If your design requires it, also subcribe the DrawSubitem
event.
At this point, you can draw anything in the related areas of your ListView.
In the example, I've painted a little symbol in the Header area.
The Header text needs to be painted too.
If the Background color doesn't change (same as in design mode), you just need to use the DrawListViewItemEventArgs e
parameter function e.DrawBackground();
If not, use e.Graphics.FillRectangle()
to color the Item area, defined by e.Bounds
.
The Item Text is drawn using e.Graphics.DrawString()
.
The item Text is e.Item.Text
, the text area is defined by e.Bounds
again.
If you don't need any specific details/settings for the item's text, you can simply use e.DrawText();
, which uses the default properties (defined at design-time).
Here, the item color complex logic is that the color is specified inside the item text. Could be anything else. The item tag, its Index position, a List<Parameters>
, you name it.
This is how it might look like:
(I added e.Graphics.TextRenderingHint = []
to show how you can control the quality of the rendered text. e.Graphics.TextContrast
can be also used to enhance the contrast).
Note: this code sample only draws a generic image, if the ListView has an ImageList. You should also verify whether the SmallIcon/LargeIcon ImageLists are defined and draw the related Image in the specified size. It's the same procedure, though.
protected void listView1_DrawItem(object sender, DrawListViewItemEventArgs e)
{
e.Item.UseItemStyleForSubItems = true;
int imageOffset = 0;
Rectangle rect = e.Item.Bounds;
bool drawImage = !(e.Item.ImageList is null);
Color itemColor = Color.FromName(e.Item.Text.Substring(e.Item.Text.LastIndexOf(" ") + 1));
using (StringFormat format = new StringFormat(StringFormatFlags.FitBlackBox)) {
format.LineAlignment = StringAlignment.Center;
if (drawImage) {
imageOffset = e.Item.ImageList.ImageSize.Width + 1;
rect.Location = new Point(e.Bounds.X + imageOffset, e.Item.Bounds.Y);
rect.Size = new Size(e.Bounds.Width - imageOffset, e.Item.Bounds.Height);
e.Graphics.DrawImage(e.Item.ImageList.Images[e.Item.ImageIndex], e.Bounds.Location);
}
if (e.Item.Selected) {
using (SolidBrush bkgrBrush = new SolidBrush(itemColor))
using (SolidBrush foreBrush = new SolidBrush(e.Item.BackColor)) {
e.Graphics.FillRectangle(bkgrBrush, rect);
e.Graphics.DrawString(e.Item.Text, e.Item.Font, foreBrush, rect, format);
}
e.DrawFocusRectangle();
}
else {
//e.DrawDefault = true;
using (SolidBrush foreBrush = new SolidBrush(itemColor)) {
e.Graphics.DrawString(e.Item.Text, e.Item.Font, foreBrush, rect, format);
}
}
}
}
// Draws small symbol in the Header beside the normal Text
protected void listView1_DrawColumnHeader(object sender, DrawListViewColumnHeaderEventArgs e)
{
e.DrawBackground();
string extra = (e.ColumnIndex == 1) ? (char)32 + "\u2660" + (char)32 : (char)32 + "\u2663" + (char)32;
e.Graphics.DrawString(extra + e.Header.Text, e.Font, new SolidBrush(e.ForeColor), e.Bounds, StringFormat.GenericTypographic);
}