C#:如何更改列表框行的颜色?

38

我正在尝试更改 ListBox 中一些行的背景颜色。我有两个列表,一个显示为 ListBox 中的名称列表,另一个具有与第一个列表相似的某些值。当单击按钮时,我想搜索 ListBox 和第二个列表,并更改 ListBox 中那些出现在第二个列表中的值的颜色。我的 ListBox 搜索如下:

for (int i = 0; i < listBox1.Items.Count; i++)
{
    for (int j = 0; j < students.Count; j++)
    {
        if (listBox1.Items[i].ToString().Contains(students[j].ToString()))
        {
        }
    }
}

但我不知道该使用哪种方法来改变 ListBox 行的外观。有人能帮帮我吗?

**编辑:**

嗨,我将我的代码编写如下:

private void ListBox1_DrawItem(object sender, DrawItemEventArgs e)
{
    e.DrawBackground();
    Graphics g = e.Graphics;
    Brush myBrush = Brushes.Black;
    Brush myBrush2 = Brushes.Red;
    g.FillRectangle(new SolidBrush(Color.Silver), e.Bounds);
    e.Graphics.DrawString(listBox1.Items[e.Index].ToString(), e.Font, myBrush, e.Bounds, StringFormat.GenericDefault);
    for (int i = 0; i < listBox1.Items.Count; i++)
    {
        for (int j = 0; j < existingStudents.Count; j++)
        {
            if (listBox1.Items[i].ToString().Contains(existingStudents[j]))
            {
                e.Graphics.DrawString(listBox1.Items[i].ToString(),
                e.Font, myBrush2, e.Bounds, StringFormat.GenericDefault);
            }
        }
    }
    e.DrawFocusRectangle();
}

现在它把我的List画在ListBox中,但是当我第一次点击按钮时,它只以红色显示在List中的学生,当我点击ListBox时,它则绘制所有元素。我希望它能够显示所有元素,并且当我点击按钮时,它会将所有元素和在List中找到的元素以红色显示。我哪里错了?


1
使用OwnerDraw自己画出来:http://www.c-sharpcorner.com/UploadFile/sahuja/OwnerDrawListBox11212005014826AM/OwnerDrawListBox.aspx - Michael Todd
1
可能是 http://stackoverflow.com/questions/1243870/changing-selected-itms-color-in-a-listbox 的重复问题。 - Michael Todd
你的条件是什么,使得一条记录改变颜色而其他记录显示相同的颜色?你如何通过编程来区分它们的不同之处? - Michael Todd
在我的程序中,我正在获取学生的蓝牙MAC地址,并将它们与那一刻现有的MAC地址进行比较。在扫描之前,我的列表框显示所有组的列表。扫描后,必须突出显示存在的学生。为此,我正在比较Listbox1.items[i].Contains(existingstudents[i]),这会给我那一刻存在的学生姓名。这个想法是可行的,但更改特定用户的列表框颜色不起作用。 - Ercan
在绘制文本之前先绘制背景,因为先绘制文本会删除字符串。e.DrawFocusRectangle(); e.Graphics.DrawString(listBox1.Items[e.Index].ToString(), e.Font, myBrush, e.Bounds, StringFormat.GenericDefault); - MrAlex6204
显示剩余3条评论
8个回答

40

我发现使用ListView而不是ListBox可以改变列表项的BackColor。

private void listView1_Refresh()
{
    for (int i = 0; i < listView1.Items.Count; i++)
    {
        listView1.Items[i].BackColor = Color.Red;
        for (int j = 0; j < existingStudents.Count; j++)
        {
            if (listView1.Items[i].ToString().Contains(existingStudents[j]))
            {
                listView1.Items[i].BackColor = Color.Green;
            }
        }
    }
}

6
我漏掉了什么吗?问题是关于ListBox,而答案是关于ListView控件。 - Rwiti

25

您需要自己绘制该项。将DrawMode更改为OwnerDrawFixed并处理DrawItem事件。

/// <summary>
/// Handles the DrawItem event of the listBox1 control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="System.Windows.Forms.DrawItemEventArgs"/> instance containing the event data.</param>
private void listBox1_DrawItem( object sender, DrawItemEventArgs e )
{
   e.DrawBackground();
   Graphics g = e.Graphics;

    // draw the background color you want
    // mine is set to olive, change it to whatever you want
    g.FillRectangle( new SolidBrush( Color.Olive), e.Bounds );

    // draw the text of the list item, not doing this will only show
    // the background color
    // you will need to get the text of item to display
    g.DrawString( THE_LIST_ITEM_TEXT , e.Font, new SolidBrush( e.ForeColor ), new PointF( e.Bounds.X, e.Bounds.Y) );

    e.DrawFocusRectangle();
}

谢谢您的评论,但我该如何使用这个函数?或者在哪里使用它?我已经在listbox的属性中更改了Drawmode = OwnerDrawFixed,在InitializeComponent()中是否需要更正一些内容?还是我只需将此函数添加到我的Form1.cs函数中并调用它即可? - Ercan
1
我是一个VS设计师的粉丝。因此,在表单编辑器中,您的列表框所在位置进入事件列表,并为DrawItem事件创建一个新处理程序。然后在您的新事件处理程序中使用上述代码。 - Justin
使用绘制项处理程序:listBox1.DrawMode = DrawMode.OwnerDrawFixed; listBox1.DrawItem += new DrawItemEventHandler(listBox1_DrawItem); - Harrichael
如果您想要相同的项目文本,而不是THE_LIST_ITEM_TEXT,您可以将其替换为(sender as ListBox).Items[e.Index].ToString() - Alex P.
这个答案看起来是正确的,我尝试使用LISTBOX实现颜色,颜色可以正常工作,但如果添加足够多的行使滚动条出现,渲染就会变得非常混乱。它无法使用。 - Yogurtu

19

首先使用这个命名空间:

using System.Drawing;
在你的表单中任何位置添加以下内容:
listBox.DrawMode = DrawMode.OwnerDrawFixed;
listBox.DrawItem += listBox_DrawItem;

这是事件处理程序:

private void listBox_DrawItem(object sender, DrawItemEventArgs e)
{
     e.DrawBackground();

     Graphics g = e.Graphics;
     g.FillRectangle(new SolidBrush(Color.White), e.Bounds);
     ListBox lb = (ListBox)sender;
     g.DrawString(lb.Items[e.Index].ToString(), e.Font, new SolidBrush(Color.Black), new PointF(e.Bounds.X, e.Bounds.Y));

     e.DrawFocusRectangle();
}

2
我认为你需要自己绘制列表项才能实现这一点。
这里有一个相同类型问题的帖子

2

在将列表框项目添加到表单后,从属性面板中使用OwnerDrawFixed选项更改DrawMode。如果您忘记执行此操作,则以下任何代码都不起作用。然后从事件区域单击DrawItem事件。

private void listBox1_DrawItem(object sender, DrawItemEventArgs e)
{
   // 1. Get the item
   string selectedItem = listBox1.Items[e.Index].ToString();
                    
   // 2. Choose font 
   Font font = new Font("Arial", 12);
        
   // 3. Choose colour
   SolidBrush solidBrush = new SolidBrush(Color.Red);
        
   // 4. Get bounds
   int left = e.Bounds.Left;
   int top = e.Bounds.Top;
                    
   // 5. Use Draw the background within the bounds
   e.DrawBackground();
        
   // 6. Colorize listbox items
   e.Graphics.DrawString(selectedItem, font, solidBrush, left, top);
}

0

我找到了将列表框项目背景设置为黄色的解决方案。我尝试了以下方法来实现这个效果。

 for (int i = 0; i < lstEquipmentItem.Items.Count; i++)
                {
                    if ((bool)ds.Tables[0].Rows[i]["Valid_Equipment"] == false)
                    {
                        lblTKMWarning.Text = "Invalid Equipment & Serial Numbers are highlited.";
                        lblTKMWarning.ForeColor = System.Drawing.Color.Red;
                        lstEquipmentItem.Items[i].Attributes.Add("style", "background-color:Yellow");
                        Count++;
                    }

                }

0
我所做的方式还允许您在选择该项目时更改背景颜色。
private void lbLog_DrawItem(object sender, DrawItemEventArgs e)
{
    Graphics g = e.Graphics;
    Color color;

    if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)
        color = Color.Blue;
    else
        color = e.Index % 2 == 0 ? Color.Gray : Color.White;

    g.FillRectangle(new SolidBrush(color), e.Bounds);
    g.DrawString(lbLog.Items[e.Index].ToString(), e.Font, new SolidBrush(Color.Black), e.Bounds, StringFormat.GenericDefault);

    e.DrawFocusRectangle();
}

-6

怎么样?

      MyLB is a listbox

        Label ll = new Label();
        ll.Width = MyLB.Width;
        ll.Content = ss;
        if(///<some condition>///)
            ll.Background = Brushes.LightGreen;
        else
            ll.Background = Brushes.LightPink;
        MyLB.Items.Add(ll);

2
很明显你从未尝试过那段代码。它不起作用,甚至无法编译。看起来你是一名Java程序员。在Java中是这样做的。但是C#完全不同。 - Elmue
你为什么期望它能编译?这是元代码。 嗯,我已经设计和编写代码大约50年了:) 显然,如果你只会寻找复制/粘贴答案,我不会雇用你。 - Dan Hed
3
这段代码烂透了。你不能将标签放入列表框中。这表明你连50年都不可能学会C#编程。 - Elmue

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接