根据类中的值突出显示 ListBox 项
Posted
技术标签:
【中文标题】根据类中的值突出显示 ListBox 项【英文标题】:Highlight ListBox items based on value from class 【发布时间】:2020-08-19 19:07:20 【问题描述】:是否可以通过检查类的值来循环遍历 ListBox 中的项目并以某种方式突出显示或指示项目不可用?
基本上,获得了一个 Game 类并在存储的信息中 Game 是否可用,因此我需要在循环 ListBox 项目时检查这个类,并以某种方式在 ListBox 上指示是否 GameAvailable = false。
到此为止,不知道如何继续:
private void HighlightUnavailable()
foreach(string item in listbox_consoles.Items)
foreach (Products.Game game in GameService.AllGames())
if (item == game.GameName.ToString())
if (game.GameAvailable)
【问题讨论】:
为什么不删除不需要的项目(使用GameAvailable == false
)?
@DmitryBychenko 它是一个表单,用户可以在其中显示所有可用游戏,但需要在列表中指明哪些产品可用。
这是什么? WinForms、WPF、..等等?
@JQSOFT 道歉,我应该一开始就提到 - 它是 WinForms。
【参考方案1】:
是的,可以这样:
将 ListBox 绑定到 GameService.AllGames()
,我相信它会返回 Game
对象的列表或数组。
将ListBox.DrawMode 设置为DrawMode.OwnerDrawFixed
并处理ListBox.DrawItem 事件以根据它们的GameAvailable
属性绘制项目。
假设控件名称为Form1
和listBox1
,添加Form1
构造函数:
public Form1()
InitializeComponent();
//...
listBox1.DrawMode = DrawMode.OwnerDrawFixed;
listBox1.DrawItem += (s, e) => OnListBoxDrawItem(s, e);
listBox1.DataSource = GameService.AllGames();
假设你想用绿色显示可用的游戏,用红色的前景色显示其余游戏。
private void OnListBoxDrawItem(object sender, DrawItemEventArgs e)
//Comment if you don't need to show the selected item(s)...
e.DrawBackground();
if (e.Index == -1) return;
var game = listBox1.Items[e.Index] as Game;
var foreColor = game.GameAvailable ? Color.Green : Color.Red;
//Pass the listBox1.BackColor instead of the e.BackColor
//if you don't need to show the selection...
TextRenderer.DrawText(e.Graphics, game.GameName, e.Font,
e.Bounds, foreColor, e.BackColor,
TextFormatFlags.Left | TextFormatFlags.VerticalCenter);
...或使用不同的背景颜色:
private void OnListBoxDrawItem(object sender, DrawItemEventArgs e)
if (e.Index == -1) return;
var game = listBox1.Items[e.Index] as Game;
var backColor = e.State.HasFlag(DrawItemState.Selected)
? e.BackColor
: game.GameAvailable
? Color.LightGreen
: listBox1.BackColor;
//Or this if you don't need to show the selection ...
//var backColor = game.GameAvailable
// ? Color.LightGreen
// : listBox1.BackColor;
using (var br = new SolidBrush(backColor))
e.Graphics.FillRectangle(br, e.Bounds);
TextRenderer.DrawText(e.Graphics, game.GameName, e.Font,
e.Bounds, Color.Black, backColor,
TextFormatFlags.Left | TextFormatFlags.VerticalCenter);
...或者从您的资源中使用一对是 和没有 图像:
Bitmap YesImage, NoImage;
public Form1()
InitializeComponent();
//...
YesImage = Properties.Resources.YesImage;
NoImage = Properties.Resources.NoImage;
listBox1.DrawMode = DrawMode.OwnerDrawFixed;
listBox1.DrawItem += (s, e) => OnListBoxDrawItem(s, e);
listBox1.DataSource = GameService.AllGames();
this.FormClosed += (s, e) => YesImage.Dispose(); NoImage.Dispose(); ;
private void OnListBoxDrawItem(object sender, DrawItemEventArgs e)
if (e.Index == -1) return;
var game = listBox1.Items[e.Index] as Game;
var backColor = e.State.HasFlag(DrawItemState.Selected)
? e.BackColor
: listBox1.BackColor;
var bmp = game.GameAvailable ? YesImage : NoImage;
var rectImage = new Rectangle(
3, e.Bounds.Y + ((e.Bounds.Height - bmp.Height) / 2),
bmp.Width, bmp.Height
);
var rectTxt = new Rectangle(
rectImage.Right + 3, e.Bounds.Y,
e.Bounds.Right - rectImage.Right - 3,
e.Bounds.Height
);
using (var br = new SolidBrush(backColor))
e.Graphics.FillRectangle(br, e.Bounds);
e.Graphics.DrawImage(bmp, rectImage);
TextRenderer.DrawText(e.Graphics, game.GameName, e.Font,
rectTxt, Color.Black, backColor,
TextFormatFlags.Left | TextFormatFlags.VerticalCenter);
【讨论】:
谢谢,这很好用!选择是/否图像,我认为这看起来最好。 请问你的红色和绿色图标是从哪里得到的?我得到的那些看起来不如你预览的那些。谢谢! @Pawel Here buddy i.stack.imgur.com/Xzh8t.png 和 i.stack.imgur.com/FZqUz.png以上是关于根据类中的值突出显示 ListBox 项的主要内容,如果未能解决你的问题,请参考以下文章
ListBox 选择时禁用突出显示 - Windows Phone 7