neo
neo

Reputation: 293

Highlighting strings in richtextBox

I need to highlight all words in richtextBox that are listed in .xls file, here's a part of my code:

public void HighlightWords(RichTextBox rtb1, DataTable dtXLS)
{
    for (int i = 0; i < dtXLS.Rows.Count; i++)
    {
        string[] wordsToRedact = new string[dtXLS.Rows.Count];

        wordsToRedact[i] = dtXLS.Rows[i][0].ToString();

        Regex test = new Regex(@"[\p{P}|\s](" + wordsToRedact[i] + @")[\p{P}|\s]", RegexOptions.Singleline | RegexOptions.Compiled);
        MatchCollection matchlist = test.Matches(rtb1.Text);

        if (matchlist.Count > 0)
        {
            for (int j = 0; j < matchlist.Count; j++)
            {
                WordsToRedact words = new WordsToRedact(matchlist[j]);
                HighLighting highLight = new HighLighting();
                highLight.Highlight_Words(rtb1, words);
            }
        }
    }
}

class HighLighting
{
    public void Highlight_Words(RichTextBox rtb, WordsToRedact e)
    {
        rtb.SelectionBackColor = Color.LightSkyBlue;
        rtb.SelectionStart = e.index;
        rtb.SelectionLength = e.length;

        rtb.ScrollToCaret();
    }
}

class WordsToRedact
{
    public int index;
    public int length;
    public string value;

    public WordsToRedact(Match m)
    {
        this.index = m.Groups[1].Index;
        this.length = m.Groups[1].Length;
        this.value = m.Groups[1].Value;
    }   
}

The problem is, it didn't highlight some of the words that also matches the regex. Some are highlighted but some are not. Accuracy is my problem, and I don't know where I am getting wrong.

Upvotes: 0

Views: 1280

Answers (3)

neo
neo

Reputation: 293

mahdi-tahsildari's answer did answer my problem! But in addition with his answer I want also to post the other option that I've tried that also fixed the issue.

I changed the HighLighting class to this codes:

class HighLighting
{
    public void HighlightText(RichTextBox rtb, string word)
    {
        int s_start = rtb.SelectionStart, startIndex = 0, index;

        while ((index = rtb.Text.IndexOf(word, startIndex)) != -1)
        {
            rtb.Select(index, word.Length);
            rtb.SelectionBackColor = Color.Yellow;

            startIndex = index + word.Length;
        }

        rtb.SelectionStart = s_start;
        rtb.SelectionLength = 0;
        rtb.SelectionColor = Color.Black;
        rtb.ScrollToCaret();
    }
}

and everything goes fine. this code and mahdi-tahsildari's answer did the same thing! Thanks for all your help! :))

Upvotes: 0

Mahdi Tahsildari
Mahdi Tahsildari

Reputation: 13582

I checked your code, there were some problems in it, i list them below :
first :

for (int i = 0; i < dtXLS.Rows.Count; i++)
{
    string[] wordsToRedact = new string[dtXLS.Rows.Count];
    ...  

is wrong, you should initialize your string array before the for loop otherwise it gets renewed in each loop iteration, do this :

string[] wordsToRedact = new string[listBox1.Items.Count];
for (int i = 0; i < dtXLS.Rows.Count; i++)
{
   ...

second : (your major problem)
you should color the selected part after it is selected not before, that is why your code does not select the last match, you should do this :

rtb.SelectionStart = e.index;
rtb.SelectionLength = e.length;
rtb.SelectionBackColor = Color.LightSkyBlue;

and Last : (with doubt) I think but I am not sure that you should use index zero [0] not [1]

public WordsToRedact(Match m)
{
    this.index = m.Groups[0].Index;
    this.length = m.Groups[0].Length;
    this.value = m.Groups[0].Value; 
}

Upvotes: 1

Jacob Seleznev
Jacob Seleznev

Reputation: 8131

This will work:

Regex test = new Regex(@"\b(" + wordsToRedact[i] + @")\b", 
RegexOptions.Singleline | RegexOptions.Compiled);

Upvotes: 0

Related Questions