根据类中的值突出显示 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 属性绘制项目。

假设控件名称为Form1listBox1,添加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

从 ListBox 的 ListBox 中删除突出显示

Qt:如何突出显示 QListWidget 中的重复项? (qtjambi)

SQL如何在某些情况下突出显示重复项

使用 JS 数组突出显示特定类中的单词

切换 div 并突出显示当前菜单项