RichTextBox - 如何突出显示行尾?

RichTextBox - How highlight end of line?

如果搜索到的词在的行首或行尾,我想给它上色。如果它在线的中间则不是彩色的。我尝试了很多东西,但效果不佳。

似乎该行的开头正在运行。但是第一行的结尾只能着色。我想为所有行结束着色。我想我需要每一行开始和循环的索引,但我做不到。

我该如何解决?

 private void button1_Click(object sender, EventArgs e)
    {
        int wordLength = textBox1.Text.Length;
        string word = textBox1.Text;     
        for (int i = 0; i < richTextBox1.Lines.Count(); i++)
        {                
            int startIndex = richTextBox1.GetFirstCharIndexFromLine(i);
            richTextBox1.Find(word, startIndex, startIndex+wordLength, RichTextBoxFinds.None);
            richTextBox1.SelectionColor = Color.Red;
            richTextBox1.SelectionBackColor = Color.Yellow;

            int newLineIndex = richTextBox1.Lines[i].Length;
            richTextBox1.Find(textBox1.Text, (newLineIndex - wordLength), newLineIndex, RichTextBoxFinds.None);
            richTextBox1.SelectionColor = Color.Red;
            richTextBox1.SelectionBackColor = Color.Yellow;
        }         

尝试:

 int newLineIndex = i + 1 < richTextBox1.Lines.Length ? richTextBox1.GetFirstCharIndexFromLine(i + 1) - 1 : richTextBox1.TextLength;

我建议稍微更改一下您的代码。当 RichTextBox 文本长度增长时,您会注意到原因。
询问 Lines[] 内容并不是一件好事,在循环中更糟糕,当您可能多次访问此 属性 时。
您可以在 .Net Source Code 中看到发生了什么(每次 - Lines 属性 值未被缓存且不能被缓存)。

GetLineFromCharIndex()GetFirstCharIndexFromLine() 使用 SendMessageEM_LINEFROMCHAREM_LINEINDEX 消息发送到使用缓存值的编辑控件,并且是相当快。

  • 使用Regex.Matches()收集匹配词的索引(可以使用多个词,用竖线分隔:"|",但这里我们只处理一个词。当匹配多个单词时,使用 List<Match>Match.Length 而不是 searchWord.Length) 并仅提取每个匹配项的索引位置。
  • 然后循环索引,检查当前索引位置是否满足条件。
  • IndexOf("\n", [StartPosition])找到当前行结尾,使用第一行索引(也用于选择)作为起始位置。

RichTextBox控件只使用\n作为行分隔符,所以我们不用担心\r.

string searchWord = "John";
var txt = richTextBox1.Text;
int textLenght = txt.Length;

// the indexes list can be created with the alternative method (using IndexOf() in a loop) 
var indexes = Regex.Matches(txt, searchWord, RegexOptions.Multiline)
                   .OfType<Match>()
                   .Select(m => m.Index).ToList();

foreach (int index in indexes) {
    int currentLine = richTextBox1.GetLineFromCharIndex(index);
    int lineFirstIndex = richTextBox1.GetFirstCharIndexFromLine(currentLine);
    int lineLastIndex = txt.IndexOf("\n", lineFirstIndex);

    if (index == lineFirstIndex ||
        index == lineLastIndex - searchWord.Length ||
        index == textLenght - searchWord.Length) {
        richTextBox1.Select(index, searchWord.Length);
        richTextBox1.SelectionColor = Color.Red;
    }
}

编辑:由于Regex.Matches不允许,您可以在循环中使用IndexOf()

var indexes = new List<int>();
int wordPosition = -1;
do {
    if ((wordPosition = txt.IndexOf(searchWord, wordPosition + 1)) >= 0) {
        indexes.Add(wordPosition);
    }
} while (wordPosition >= 0);