简体   繁体   中英

How to have multiple colors in a listview row?

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

SO70601333

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM