简体   繁体   中英

How do I dynamically change the font of winforms listbox item?

How do I make bold a variable amount of items in a listbox? I've seen solutions like this one , but it appears to only work if I know exactly which items should be bold before runtime. Here's my specific case:

I have a listbox with a list of strings read from a file. I have a search bar that, when typed in, will automatically move items matching that string to the top of the listbox. Unfortunately, being at the top isn't enough of an indicator of "search result," so I also want to make those items bold. Before runtime, I do know all the items I want to be bold will be at the top of the list, but I have no idea how many items that will be. Additionally, when the user erases the search bar's contents, the list will be reordered to its initial order and the bold items should be made not bold.

How do I go back and forth between bold/not bold for specific listbox items at runtime?

Here is my code for the search and display functionality:

    private void txtSearch_TextChanged(object sender, EventArgs e)
    {
        string searchTerm = txtSearch.Text.Trim();
        if(searchTerm.Trim() == "") // If the search box is blank, just repopulate the list box with everything
        {
            listBoxAllTags.DataSource = fullTagList;
            return;
        }

        searchedTagList = new List<UmfTag>();
        foreach(UmfTag tag in fullTagList)
        {
            if(tag.ToString().ToLower().Contains(searchTerm.ToLower()))
            {
                searchedTagList.Add(tag);
            }
        }

        // Reorder the list box to put the searched tags on top. To do this, we'll create two lists:
        // one with the searched for tags and one without. Then we'll add the two lists together.
        List<UmfTag> tempList = new List<UmfTag>(searchedTagList);
        tempList.AddRange(fullTagList.Except(searchedTagList));
        listBoxAllTags.DataSource = new List<UmfTag>(tempList);
    }

I was able to solve my own problem. I indeed used the solution present in this question , but I altered it like so:

    private void listBoxAllTags_DrawItem(object sender, DrawItemEventArgs e)
    {
        e.DrawBackground();
        FontStyle fontStyle = FontStyle.Regular;
        if(e.Index < searchedTagList.Count)
        {
            fontStyle = FontStyle.Bold;
        }
        if(listBoxAllTags.Items.Count > 0) // Without this, I receive errors
        {
            e.Graphics.DrawString(listBoxAllTags.Items[e.Index].ToString(), new Font("Arial", 8, fontStyle), Brushes.Black, e.Bounds);
        }
        e.DrawFocusRectangle();
    }

The second if statement (checking if the count is greater than 0) is required. Without it, I received "index[-1]" errors because my program first starts with empty listboxes, and the DrawString method couldn't draw the string for the empty listBox.Items[] array.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM