如何在 Winforms 中有一个 ListBox 的多色项目?
How to have a multi-coloured items of a ListBox in winforms?
我正在用 winforms 开发一个软件,我卡在了一个步骤
List<KeyValuePair<string, string>>.
和一些示例数据:
List <KeyValuePair<"S", "1200">>
List <KeyValuePair<"S", "1300">>
List <KeyValuePair<"L", "1400">>
我想在 ListBox 中显示键对的值,基于键对,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 属性 到 OwnerDrawVariable
或 OwnerDrawFixed
(后者会将所有项目设置为相同的高度)。
注意 → 这里我设置为OwnerDrawVariable
列表Items
绘画需要在DrawItem event of the ListBox, using the DrawItemEventArgs 的Graphics 对象中执行。这允许在 ListBox 或 Form 需要重新绘制时正确刷新 Items
。
1 - 您不必 乘 您的 Graphics 对象。
2 - 也不需要 foreach
循环,因为当您 create/modify ListBox Items
集合时,每个项目都会被绘制。
注意 → 我正在按照您在代码中显示的方式绘制 Items
背景,但视觉效果可能有点奇怪(那些颜色混合不好)。
首先,模拟您的 GetItac.FilterWorkOrders()
方法的结果,它将 return 一个 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();
您也可以这样编码,如果该方法实际上 return 是 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 字体。
对于绘制的每个项目,选择文本颜色测试 KeyValuePair<string, string>
的 Key
:如果其值为 "S"
,则文本颜色设置为 Color.Red
,背景色改为Color.Olive
。否则它们被设置为 Color.Blue
和 Color.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;
}
我正在用 winforms 开发一个软件,我卡在了一个步骤
List<KeyValuePair<string, string>>.
和一些示例数据:
List <KeyValuePair<"S", "1200">>
List <KeyValuePair<"S", "1300">>
List <KeyValuePair<"L", "1400">>
我想在 ListBox 中显示键对的值,基于键对,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 属性 到 OwnerDrawVariable
或 OwnerDrawFixed
(后者会将所有项目设置为相同的高度)。
注意 → 这里我设置为OwnerDrawVariable
列表Items
绘画需要在DrawItem event of the ListBox, using the DrawItemEventArgs 的Graphics 对象中执行。这允许在 ListBox 或 Form 需要重新绘制时正确刷新 Items
。
1 - 您不必 乘 您的 Graphics 对象。
2 - 也不需要 foreach
循环,因为当您 create/modify ListBox Items
集合时,每个项目都会被绘制。
注意 → 我正在按照您在代码中显示的方式绘制 Items
背景,但视觉效果可能有点奇怪(那些颜色混合不好)。
首先,模拟您的 GetItac.FilterWorkOrders()
方法的结果,它将 return 一个 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();
您也可以这样编码,如果该方法实际上 return 是 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 字体。
对于绘制的每个项目,选择文本颜色测试 KeyValuePair<string, string>
的 Key
:如果其值为 "S"
,则文本颜色设置为 Color.Red
,背景色改为Color.Olive
。否则它们被设置为 Color.Blue
和 Color.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;
}