如何在winforms中拥有ListBox的多色项?

问题描述 投票:2回答:1

我正在开发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项目应该是蓝色的。

希望你能帮助我。

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

        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 listbox listboxitem
1个回答
1
投票

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

列表Items绘画必须使用DrawItem ListBox对象在DrawItemEventArgse.Graphics事件中执行。当Items / ListBox需要重新绘制时,这允许正确刷新Form

1 - 您不必将Graphics对象相乘。 2 - 也不需要foreach循环,因为在创建/修改ListBox 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());

ListBox Items集合被填满时,DrawItem事件将被提升,以允许绘制Items内容。 您可能需要添加MeasureItem事件,以确保对每个项目的高度进行正确测量(如果您计划修改ListBox字体,则必须使用该项。

对于绘制的每个项目,选择文本颜色测试KeyKeyValuePair<string, string>:如果其值为"S",则文本颜色设置为Color.Red,背景颜色为Color.Olive。否则他们将被设置为Color.BlueColor.Aquamarine

private void listBox1_DrawItem(object sender, DrawItemEventArgs e)
{
    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 (SolidBrush backColorBrush = new SolidBrush(backColor))
    using (SolidBrush foreColorBrush = new SolidBrush(textColor))
    {
        e.Graphics.FillRectangle(backColorBrush, e.Bounds);
        e.Graphics.DrawString(workOrders[e.Index].Value, listBox1.Font, foreColorBrush, 
                              e.Bounds, StringFormat.GenericTypographic);
    }
}

private void listBox1_MeasureItem(object sender, MeasureItemEventArgs e)
{
    e.ItemHeight = listBox1.Font.Height;
}
© www.soinside.com 2019 - 2024. All rights reserved.