WinForms:在ListView中更改选定项目的ForeColor [英] WinForms: Changing ForeColor of Selected item in ListView
问题描述
我将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
模式,然后订阅其DrawItem
和DrawColumnHeader
事件.
如果您的设计需要它,请订阅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屋!