Предлагаю немного изменить ваш код. Вы заметите, почему, когда длина текста RichTextBox увеличивается.
Запрашивать контент Lines[]
- это не совсем хорошо, что гораздо хуже в oop, когда вы получаете доступ к этому свойству, вероятно, много раз.
В . Net Исходный код вы можете видеть, что происходит (каждый раз - значения Lines
свойства не кэшируются и не могут быть).
GetLineFromCharIndex()
и GetFirstCharIndexFromLine()
используют вместо SendMessage
отправку сообщений EM_LINEFROMCHAR
и EM_LINEINDEX
в элемент управления Edit - который использует кэшированные значения - и работают довольно быстро.
- Используйте
Regex.Matches()
, чтобы собрать индексы совпадающих слов (вы можете использовать более одного слова, разделенных каналом: "|"
, но здесь мы обрабатываем только одно слово. При сопоставлении более чем одного слова используйте List<Match>
и Match.Length
вместо searchWord.Length
) и извлекайте только позицию индекса каждого соответствия. - Затем l oop индексов и проверьте, соответствует ли текущая позиция индекса критериям.
- Текущий конец строки находится с
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()
в oop:
var indexes = new List<int>();
int wordPosition = -1;
do {
if ((wordPosition = txt.IndexOf(searchWord, wordPosition + 1)) >= 0) {
indexes.Add(wordPosition);
}
} while (wordPosition >= 0);