WinForms:在ListView中更改选定项目的ForeColor [英] WinForms: Changing ForeColor of Selected item in ListView

查看:174
本文介绍了WinForms:在ListView中更改选定项目的ForeColor的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将ListView中所有项目的ForeColor设置为不同的颜色,但是在选择该项目时会覆盖此颜色(再次更改为Black;取消选择时更改为自定义颜色).

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 custom color on deselection).

我希望我的物品即使在选择时也能保留我的自定义颜色.

I want my items to retain my custom color, even in selection.

我基本上是在问与

I'm basically asking the same question that was asked here 7 years ago, and doesn't seem to have any satisfactory answer.

我尝试在SO和其他地方搜索,但没有运气.到目前为止,提供的唯一解决方案是绘制整个内容(DrawItem方法),我尝试了一下,但是对于这样的小要求却非常复杂...

I tried searching in SO and elsewhere, and no luck. The only solution provided so far is to draw the whole thing (the DrawItem method), which I gave a try but is ridiculously complicated for such a petty requirement...

这是唯一的方法吗?说的不是那样.

Is this the only way? Say it ain't so.

推荐答案

启用ListView OwnerDraw模式,然后订阅其DrawItemDrawColumnHeader事件.
如果您的设计需要它,请订阅DrawSubitem事件.

Enable your ListView OwnerDraw mode, then subscribe its DrawItem and DrawColumnHeader events.
If your design requires it, also subcribe the DrawSubitem event.

这时,您可以在ListView的相关区域中绘制任何内容.

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.

如果背景色不变(与设计模式下相同),则只需使用DrawListViewItemEventArgs e参数功能e.DrawBackground();

If the Background color doesn't change (same as in design mode), you just need to use the DrawListViewItemEventArgs e parameter function e.DrawBackground();

如果没有,请使用e.Graphics.FillRectangle()e.Bounds定义的项目区域着色.

If not, use e.Graphics.FillRectangle() to color the Item area, defined by e.Bounds.

项目文本是使用e.Graphics.DrawString()绘制的.
文本项为e.Item.Text文本区域e.Bounds再次定义.
如果您不需要该项文本的任何特定详细信息/设置,则可以简单地使用 e.DrawText(); ,它使用默认属性(在设计时定义) .

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).

在这里,项目颜色复杂逻辑是该颜色是在项目文本内指定的.可以是其他任何东西.项目标签,它的索引位置,List<Parameters>,您将其命名.

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.

这可能是这样的:
(我添加了e.Graphics.TextRenderingHint = []来显示如何控制渲染文本的质量.e.Graphics.TextContrast也可以用来增强对比度).

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).

注意:如果ListView具有ImageList,则此代码示例仅绘制通用图像.您还应该验证是否定义了SmallIcon/LargeIcon ImageList,并以指定的大小绘制相关的Image.但这是相同的过程.

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

这篇关于WinForms:在ListView中更改选定项目的ForeColor的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆