I'm using C#/Winforms. I want to have a listview with several "background" colored rows. Colors are defined by a ColorPicker. My code works but all rows are just in one color.
A brief explanation: If the user chooses a color (below "Cor (Clique aqui para alterar)" and clicks on "Add highlight color" it is added to the list with the following line:
lstHighlightColors.Items.Add(lblColorPicker.BackColor.ToString());
but i can't seem to find a solution to have multiple colors. I want to fill the rectangles according to the color that was chosen in that row.
Here's my code:
var highlightColorslst = lstHighlightColors.Items[e.ItemIndex];
string text = highlightColorslst.Text;
text = text.Replace("Color", "");
Brush myBrush = new SolidBrush(lstHighlightColors.ForeColor);
Pen rect = new Pen(lblColorPicker.ForeColor);
lstHighlightColors.Items[e.ItemIndex].BackColor = lblColorPicker.BackColor;
Brush fillColor = new SolidBrush(lstHighlightColors.Items[e.ItemIndex].BackColor);
e.Graphics.DrawRectangle(rect, new Rectangle(e.Bounds.Left + 2, e.Bounds.Top + 2, 22, e.Bounds.Height - 4));
e.Graphics.DrawString(text, new Font(FontFamily.GenericSansSerif, 8), myBrush, (e.Bounds.Left + 25), e.Bounds.Top + 2);
e.Graphics.FillRectangle(fillColor, new Rectangle(e.Bounds.Left + 3, e.Bounds.Top + 3, 21, e.Bounds.Height - 5));
e.DrawFocusRectangle();
Here's an image of the working code:
Assuming that, you have a single-column header ListView
and the View
property is set to View.Details
.
The .ToString()
method of the Color
class does not return a color identifier (name, hex, int...), it returns - as what you have in your list shown above - the object's type and either something like "Color [Black]"
for the named/known colors and "Color [A=255, R=25, G=207, B=183]"
for the nameless ones.
You need to call the Color.Name
property when you add one into the list. The property returns either the name of a known color ( Black
) or a hex representation ( ffe43e19
) of a nameless one.
lstHighlightColors.Items.Add(lblColorPicker.BackColor.Name);
In the drawing part and for each item you draw, get the color's name/hex and call the proper Color.From*
method to create it.
Exanple
// +
// using System.Globalization;
private void listView1_DrawItem(object sender, DrawListViewItemEventArgs e)
{
var color = GetColor(e.Item.Text);
var colorRec = new Rectangle(e.Bounds.X + 2, e.Bounds.Y + 2, 22, e.Bounds.Height - 4);
var textRec = new Rectangle(colorRec.Right + 2, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height);
if (e.Item.Selected)
e.Graphics.FillRectangle(SystemBrushes.Highlight, e.Bounds);
else
e.DrawBackground();
using (var br = new SolidBrush(color))
using (var pn = new Pen(e.Item.ForeColor))
{
e.Graphics.FillRectangle(br, colorRec);
e.Graphics.DrawRectangle(pn, colorRec);
}
TextRenderer.DrawText(e.Graphics, e.Item.Text, e.Item.Font, textRec,
e.Item.Selected ? SystemColors.HighlightText : e.Item.ForeColor,
TextFormatFlags.VerticalCenter | TextFormatFlags.Left);
}
private Color GetColor(string name)
{
Color color;
if (int.TryParse(name, NumberStyles.HexNumber, CultureInfo.CurrentCulture, out var hex))
color = Color.FromArgb(hex);
else
color = Color.FromName(name);
return color;
}
Side Note: If you just need what you get from this answer, then I recommend replacing the ListView
with a ListBox
. More suitable for this requirement.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.