如何在 winforms 中拥有列表框的多色项目?



我正在用winforms开发一个软件,我被困在一个步骤中

List<KeyValuePair<string, string>>. 

和一些示例数据:

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

我想在 ListBox 中播放键对的值,其中基于对的键,ListBox 上的项具有不同的颜色,例如,如果键为 S,则项应为红色,如果键为 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的自定义绘制,将ListBoxDrawMode 属性设置为OwnerDrawVariableOwnerDrawFixed(后者将所有项设置为相同的高度(。

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

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

1 - 不必将图形对象相乘
2 - 也不需要foreach循环,因为在创建/修改 ListBoxItems集合时将绘制每个项。

请注意→我正在按照您在代码中显示的方式绘制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());

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

对于绘制的每个项目,选择文本颜色以测试KeyValuePair<string, string>Key:如果其值为"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;
}

最新更新