【问题标题】:How to have a multi-coloured items of a ListBox in winforms?如何在winforms中有一个ListBox的多色项目?
【发布时间】:2018-06-08 11:19:17
【问题描述】:

我正在用 winforms 开发一个软件,我被困在我有的一步

 List<KeyValuePair<string, string>>. 

还有一些示例数据:

List <KeyValuePair<"S", "1200">>
List <KeyValuePair<"S", "1300">>
List <KeyValuePair<"L", "1400">>

我想在 ListBox 中显示密钥对的值,根据该对的密钥,ListBox 上的 Item 具有不同的颜色,例如,如果 Key 是 S,则 Item 应该是红色并且如果 Key 是 L,则 Item 应该是蓝色的。

希望你能帮我解决这个问题。

这是我做的代码,但它没有达到预期的效果:

        e.DrawBackground();
        Graphics g = e.Graphics;
        Graphics x = e.Graphics;

        g.FillRectangle(new SolidBrush(Color.Olive), e.Bounds);
        x.FillRectangle(new SolidBrush(Color.Aquamarine), e.Bounds);

        foreach (var workOrders in GetItac.FilterWorkOrders())
        {
            if (workOrders.Key == "S")
            {
                g.DrawString(workOrders.Value, e.Font, new SolidBrush(e.ForeColor), new PointF(e.Bounds.X, e.Bounds.Y));

            }
            else
            {
                x.DrawString(workOrders.Value, e.Font, new SolidBrush(e.ForeColor), new PointF(e.Bounds.X, e.Bounds.Y));

            }

        }

【问题讨论】:

标签: c# winforms graphics listbox listboxitem


【解决方案1】:

当您需要在ListBox控件中显示自定义结果时,您需要启用列表中Items的自定义绘制,将ListBoxDrawMode属性设置为OwnerDrawVariableOwnerDrawFixed(后者会将所有项目设置为相同的高度)。

注意 → 这里我设置为OwnerDrawVariable

列表Items的绘制需要在ListBox的DrawItem事件中进行,使用DrawItemEventArgs的Graphics对象。这允许在 ListBox 或 Form 需要重新绘制时正确刷新 Items

1 - 您不必您的 Graphics 对象。
2 - 也不需要 foreach 循环,因为在创建/修改 ListBox Items 集合时,每个项目都会被绘制。

注意 → 我正在按照您在代码中显示的方式绘制Items 背景,但视觉结果可能有点奇怪(这些颜色不能很好地混合)。


首先,模拟您的GetItac.FilterWorkOrders() 方法的结果,该方法将返回List&lt;KeyValuePair&lt;string, string&gt;&gt;,将这些项目Value 添加到列表中:

using System.Collections.Generic;

List<KeyValuePair<string, string>> workOrders;

workOrders = new List<KeyValuePair<string, string>>()
{
    new KeyValuePair<string, string>("S", "1200" ),
    new KeyValuePair<string, string>("S", "1300"),
    new KeyValuePair<string, string>("L", "1400")
};
//Select().ToList() extracts the Value string from the KeyValuePair elements
listBox1.DataSource = workOrders.Select(kv => kv.Value).ToList();

如果该方法实际上返回List&lt;KeyValuePair&lt;string, string&gt;&gt;,您也可以这样编码:

workOrders = GetItac.FilterWorkOrders();
listBox1.DataSource = workOrders.Select(kv => kv.Value).ToList();
//Or
workOrders = GetItac.FilterWorkOrders();
listBox1.Items.AddRange(workOrders.Select(kv => kv.Value).ToArray());

当 ListBox Items 集合被填满时,将引发 DrawItem 事件,以允许绘制 Items 内容。
您可能需要添加 MeasureItem 事件,以确保正确测量每个项目的高度(如果您打算修改 ListBox 字体,则必须这样做。

对于绘制的每个项目,选择文本颜色测试KeyValuePair&lt;string, string&gt;Key:如果其值为"S",则文本颜色设置为Color.Red,背景颜色设置为@987654348 @。否则,它们将设置为 Color.BlueColor.Aquamarine

private void listBox1_DrawItem(object sender, DrawItemEventArgs e)
{
    var lbx = sender as ListBox;
    e.DrawBackground();
    Color textColor = (workOrders[e.Index].Key == "S") ? Color.Red : Color.Blue;
    Color backColor = (workOrders[e.Index].Key == "S") ? Color.Olive : Color.Aquamarine;

    using (var backBrush = new SolidBrush(backColor))
    using (var foreBrush = new SolidBrush(textColor))
    {
        e.Graphics.FillRectangle(backBrush, e.Bounds);
        e.Graphics.DrawString(workOrders[e.Index].Value, lbx.Font, foreBrush, 
                              e.Bounds, StringFormat.GenericTypographic);
    }
}

private void listBox1_MeasureItem(object sender, MeasureItemEventArgs e)
{
    e.ItemHeight = (sender as ListBox).Font.Height;
}

【讨论】:

  • @Omar AlMadani 好吧,我很高兴它有帮助 :)
猜你喜欢
  • 1970-01-01
  • 2011-08-22
  • 2023-03-25
  • 1970-01-01
  • 2011-01-27
  • 1970-01-01
  • 2014-03-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多