WinForms:最简单的方法在运行时更改列表框文本颜色是什么?

3

寻找一种简单的方法来为列表框项目添加彩色文本(或粗体文本)(我在Stackoverflow上看到的解决方案似乎对我的需求过于复杂)。

我一直在使用以下代码通过注释向我的列表框添加内容:

listBox1.Items.Add("Test complete!");

这行代码在我的程序中随处可见。我想把偶尔需要修改颜色的文本变成彩色,例如“测试完成!”显示为绿色。
有没有简单的即时解决方案?

2
不,你必须为所有者绘制设置ListBox并自己绘制它。 - LarsTech
2个回答

5

如果你只是想设置字体颜色或字体,那么你可以使用一点工作来进行设置,但并不是很复杂。

你需要在DrawItem事件中添加一个处理程序。

this.listBox1.DrawItem += new DrawItemEventHandler(listBox1_DrawItem);

这里有一个非常简单的处理程序,可以做到你要求的功能。

void listBox1_DrawItem(object sender, DrawItemEventArgs e)
{
    Graphics g = e.Graphics;
    Dictionary<string, object> props = (this.listBox1.Items[e.Index] as Dictionary<string, object>);
    SolidBrush backgroundBrush = new SolidBrush(props.ContainsKey("BackColor") ? (Color)props["BackColor"] : e.BackColor);
    SolidBrush foregroundBrush = new SolidBrush(props.ContainsKey("ForeColor") ? (Color)props["ForeColor"] : e.ForeColor);
    Font textFont = props.ContainsKey("Font") ? (Font)props["Font"] : e.Font;
    string text = props.ContainsKey("Text") ? (string)props["Text"] : string.Empty;
    RectangleF rectangle = new RectangleF(new PointF(e.Bounds.X, e.Bounds.Y), new SizeF(e.Bounds.Width, g.MeasureString(text, textFont).Height));

    g.FillRectangle(backgroundBrush, rectangle);
    g.DrawString(text, textFont, foregroundBrush, rectangle);

    backgroundBrush.Dispose();
    foregroundBrush.Dispose();
    g.Dispose();
}

然后,要向ListBox添加项目,你可以这样做。
this.listBox1.Items.Add(new Dictionary<string, object> { { "Text", "Something, something"},
                                                         { "BackColor", Color.Red },
                                                         { "ForeColor", Color.Green}});
this.listBox1.Items.Add(new Dictionary<string, object> { { "Text", "darkside!!" },
                                                         { "BackColor", Color.Blue },
                                                         { "ForeColor", Color.Green },
                                                         { "Font", new Font(new Font("Arial", 9), FontStyle.Bold) } });

相当简单,我想。

Tada


你正在为列表框中的每个项目添加一个新的文本框。天哪,如果用户有10,000个项目怎么办?哎呀。顺便处理一下你的画笔。 - LarsTech
@LarsTech,你说得对,使用文本框确实有点过头了。自定义一个包含这些属性的类是一个更好的选择,我想我可能把它简化了。 - Bilal Bashir
仅凭你的示例文本,我就有点想点赞了。 - user2366842
图片的最终目标当然是利用我的甜言蜜语来引起点赞。 - Bilal Bashir

0

没有办法不自己绘制ListBox中的项目。但是,使用代码实现并不难。一个简单的实现假设列表框中的项目未被删除/重新排序,只需保持一个将索引映射到颜色的字典,然后使用类似以下内容的方式进行绘制:

private void ListBox_DrawItem(object sender, DrawItemEventArgs e)
{
    var isItemSelected = ((e.State & DrawItemState.Selected) == DrawItemState.Selected);

    Color foreColor;
    if (!this.mColorsByIndex.TryGetValue(e.Index, out foreColor))
    {
        foreColor = isItemSelected ? SystemColors.HighlightText : this.mListBox.ForeColor;
    }

    var backColor = isItemSelected ? SystemColors.Highlight : this.mListBox.BackColor;
    using (var backBrush = new SolidBrush(backColor))
    {
        e.Graphics.FillRectangle(backBrush, e.Bounds);
    }

    var item = this.mListBox.Items[e.Index];
    var itemText = this.mListBox.GetItemText(item);
    const TextFormatFlags formatFlags = TextFormatFlags.Left | TextFormatFlags.VerticalCenter;
    TextRenderer.DrawText(e.Graphics, itemText, e.Font, e.Bounds, foreColor, formatFlags);
}

WinForms中进行自定义绘图,这几乎是最简单的。

请注意,ListBox.Items.Add返回您添加的项目的索引。

如果您从ListBox中删除/更改/重新排序项目,则跟上颜色关联会变得更加困难,但这会使跟踪颜色关联变得复杂,而不是绘图本身。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接