How can I make some items in a ListBox bold?

2019-02-06 06:04发布

问题:

In Visual c# Express Edition, is it possible to make some (but not all) items in a ListBox bold? I can't find any sort of option for this in the API.

回答1:

You need to change listbox's DrawMode to DrawMode.OwnerDrawFixed. Check out these articles on msdn:
DrawMode Enumeration
ListBox.DrawItem Event
Graphics.DrawString Method

Also look at this question on msdn forums:
Question on ListBox items

A simple example (both items - Black-Arial-10-Bold):

 public partial class Form1 : Form
 {
    public Form1()
    {
        InitializeComponent();

        ListBox1.Items.AddRange(new Object[] { "First Item", "Second Item"});
        ListBox1.DrawMode = DrawMode.OwnerDrawFixed;
    }

    private void ListBox1_DrawItem(object sender, DrawItemEventArgs e)
    {
        e.DrawBackground();
        e.Graphics.DrawString(ListBox1.Items[e.Index].ToString(), new Font("Arial", 10, FontStyle.Bold), Brushes.Black, e.Bounds);
        e.DrawFocusRectangle();
    }
 }


回答2:

To add to Mindaugas Mozūras's solution, I had a problem where my e.Bounds wasn't large enough and text was getting cut off. To solve this problem (thanks to a post here), you override the OnMeasureItem event and changes your DrawMode to DrawMode.OwnerDrawVariable.

In designer:

listBox.DrawMode = DrawMode.OwnerDrawVariable;

In handler:

void listBox_MeasureItem(object sender, MeasureItemEventArgs e)
{
     e.ItemHeight = 18;
}

Solved my issues of having the height cut off text.



回答3:

Following is the code demonstrating the same.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            foreach (FontFamily fam in FontFamily.Families)
            {
                listBox1.Items.Add(fam.Name);
            }
            listBox1.DrawMode = DrawMode.OwnerDrawFixed; // 属性里设置

        }

        private void listBox1_DrawItem(object sender, DrawItemEventArgs e)
        {
            e.DrawBackground();
            e.Graphics.DrawString(listBox1.Items[e.Index].ToString(), new Font(listBox1.Items[e.Index].ToString(), listBox1.Font.Size), Brushes.Black, e.Bounds);
            //e.DrawFocusRectangle();
        }
    }
}



回答4:

A more generic example that uses sender, and actually respects foreground color (if the item is selected, for example, or the user uses some another color set, where black foreground color is not really readable) and current ListBox font:

    private void listBoxDrawItem (object sender, DrawItemEventArgs e)
    {
        Font f = e.Font;
        if (e.Index == 1) //TODO: Your condition to make text bold
            f = new Font(e.Font, FontStyle.Bold);
        e.DrawBackground();
        e.Graphics.DrawString(((ListBox)(sender)).Items[e.Index].ToString(), f, new SolidBrush(e.ForeColor), e.Bounds);
        e.DrawFocusRectangle();
    }

You need to have DrawMode set to OwnerDrawFixed (for example, in designer).



回答5:

Make the selected item bold

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        ListBox1.Items.AddRange(new Object[] { "me", "myself", "bob"});

        // set the draw mode to fixed
        ListBox1.DrawMode = DrawMode.OwnerDrawFixed;
    }

    private void ListBox1_DrawItem(object sender, DrawItemEventArgs e)
    {
        // draw the background
        e.DrawBackground();

        // get the font
        Font font = new Font(e.Font, (e.State & DrawItemState.Selected) == DrawItemState.Selected ? FontStyle.Bold : FontStyle.Regular);

        // draw the text
        e.Graphics.DrawString(ListBox1.Items[e.Index].ToString(), font, new SolidBrush(ListBox1.ForeColor), e.Bounds);

        e.DrawFocusRectangle();
    }
}