How do I change the color of a word inside a listb

2019-03-01 01:09发布

问题:

I made a Form with a TextBox that accepts a word and searches a bunch of sentences to see if any of them contains that word .After that I have to appear those sentences and highlight the word .My plan is to make a ListBox and add the sentences inside of it. My problem is how to highlight the word (by changing the color I suppose) so it can be distinguished.

Is there a preferable way? I chose ListBox so I can select the sentence I'm looking for.

Edit

According to @Thorsten Dittmar directions a create an owner drawn list box.

public partial class Form1 : Form
    {
        private List<string> _items;

        public Form1()
        {
            InitializeComponent();
            _items = new List<string>();
            _items.Add("One");
            _items.Add("Two");
            _items.Add("Three");
            listBox1.DataSource = _items;
        }

        private void listBox1_DrawItem(object sender, DrawItemEventArgs e)
        {
            e.DrawBackground();
            e.DrawFocusRectangle();
            e.Graphics.DrawString(_items[e.Index],
                new Font(FontFamily.GenericSansSerif,
                    8, FontStyle.Bold),
                    new SolidBrush(Color.Red), e.Bounds);
        }
    }

How I'm going to split the sentence in order to draw only one word?

Edit2

The way I finally did it was to make two seperate components, to compine my options. One was a ListBox with all the sentences colored and the option to select one of those and the other one a RichBox with separate colored words since is to difficult to achieve that with the ListBox (for me a least).

The way I accomplished that was by using a boolean array pointing which word should be colored in each sentence.

for (int i = 0; i < words.Length; i++)
{
  if (segments[i]) //<-boolean array
  {
     rich.SelectionColor = Color.Red;
     rich.AppendText(words[i] + " ");
     rich.SelectionColor = Color.Black;
  }
  else
  {
    rich.AppendText(words[i] + " ");
  }
}

回答1:

There is no standard way of doing it in Windows Forms. You'd have to render the list items manually (create an owner drawn list box). In WPF this would be an easy task.

EDIT
Drawing only part of a string in a different font is not an easy task. What I'd try is the following:

Introduce tokens that tell you "bold start" and "bold end" - a bit like in HTML. Let's call them the same as in HTML. So your string could look like this:

Hello, I am <b>bold</b> text<b>!</b>

Now I'd tokenize my string into text that is non-bold and text that is bold. I'd get the following parts:

Hello, I am
bold
text
!

Now I'd draw each part using the following algorithm:

  1. Draw string in current format at current position x
  2. increase position x by width of the string drawn in step 1
  3. change formatting according to upcoming string
  4. goto 1

In step 2 the Graphics.MeasureString method would be called to get the width of the string.

Doing this for the 4 sample parts above would result in:

Hello, I am
Hello, I am bold
Hello, I am bold text
Hello, I am bold text !



回答2:

A simple TextBox can have its Foreground property set, but it applies to the entire text within the TextBox.

If you want specific words to be "highlighted", you either need to split the sentence in several TextBoxes (dirty), or make use of a RichTextBox



回答3:

Giannosfor, in response to your comment, you'll have to use the parameter e of the event handler to choose which item you want to hightlight (link here).

Look at the response from Shadow Wizard and particularly at the use of e.Index.

Graphics g = e.Graphics;
...
g.FillRectangle(new SolidBrush(color), e.Bounds);

Variable g represent the graphic part of your current item e. Method FillRectangle allows you to change the color of the item's background.

Edit 1:

I tried to do as you say in the comment below but it seems there is no way to hightlight only a part of a string using ListBox. To me it seems the only control that is able to support that is the RichTextBox. A solution might be to implement your own user control in the form of a list of RichTextBoxes.



回答4:

Building on @Thorsten Dittmar answer, I developed pretty much exactly what you are looking for in a single ListBox. You can find it at https://advancedlistbox.codeplex.com/.