c# - 如何在winforms中拥有一个ListBox的多种颜色的项目?

标签 c# winforms graphics listbox listboxitem

我正在winforms中开发一个软件,我陷入了一个步骤

 List<KeyValuePair<string, string>>. 

和一些示例数据:

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

我想显示 ListBox 内 key 对的值,其中基于该对的 key ,ListBox 上的 Item 具有不同的颜色,例如,如果 Key 是 S,则 Item 应该是红色,如果键是 L,则该项目应该是蓝色的。

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

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

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

            }

        }

最佳答案

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

注意 → 在这里,我将其设置为 OwnerDrawVariable

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

1 - 您不必您的 Graphics 对象。
2 - foreach也不需要循环,因为当您创建/修改列表框 Items 时,每个项目都会被绘制。收藏。

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


首先,模拟 GetItac.FilterWorkOrders() 的结果方法,它将返回 List<KeyValuePair<string, string>> ,添加这些项目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<KeyValuePair<string, string>>,您也可以这样编码。 :

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

当列表框 Items收藏已满,DrawItem将引发事件,以允许绘制 Items内容。
您可能需要添加 MeasureItem事件,以确保正确测量每个项目的高度(如果您计划修改列表框字体,则这是强制性的。

对于绘制的每个项目,选择文本颜色来测试 Key KeyValuePair<string, string>的:如果它的值为 "S" ,文本颜色设置为Color.Red ,背景颜色为Color.Olive 。否则它们将设置为 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;
}

关于c# - 如何在winforms中拥有一个ListBox的多种颜色的项目?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50759508/

相关文章:

c# - 队列的并行处理

c# - ASP.NET Core 2.0 Web 应用部署和托管

c# - Xamarin 表单按钮 OnClick

C#:如何在排序后选择 ListView 中的顶部项目

c# - Graphics.Transform 效率极低,我该怎么办?

c# - 锁定文本框中的有效字符

java - Java/GWT 开发人员的 Flex 2D 图形学习路径?

c# - 如何解决无效对象名称 'dbo.AspNetUsers' 错误?

iphone - 绘制多个相同对象的最有效方法?

scala - 如何进行与硬件无关的并行编程?