В настоящее время я пытаюсь создать цветные результаты после поиска, содержащего ключевые слова. Мой код отображает RichTextBox, содержащий текст, который был успешно найден поисковой системой.
Теперь я хочу выделить ключевые слова в тексте, сделав их полужирными и окрашенными в красный цвет. У меня есть список слов в красивой таблице строк, которую я просматриваю таким образом (rtb — это мой RichTextBox, plainText — единственный запуск из rtb, содержащий весь его текст):
rtb.SelectAll();
string allText = rtb.Selection.Text;
string expression = "";
foreach (string word in words)
{
expression = Regex.Escape(word);
Regex regExp = new Regex(expression);
foreach (Match match in regExp.Matches(allText))
{
TextPointer start = plainText.ContentStart.GetPositionAtOffset(match.Index, LogicalDirection.Forward);
TextPointer end = plainText.ContentStart.GetPositionAtOffset(match.Index + match.Length, LogicalDirection.Forward);
rtb.Selection.Select(start, end);
rtb.Selection.ApplyPropertyValue(Run.FontWeightProperty, FontWeights.Bold);
rtb.Selection.ApplyPropertyValue(Run.ForegroundProperty, "red");
}
}
Теперь я подумал, что это поможет. Но почему-то правильно выделяется только первое слово. Затем второе появление выделения начинается на два раньше, при этом выделяется правильное количество букв, но за несколько символов до фактического слова. Затем для третьего случая это еще больше символов раньше и т. д.
У вас есть идеи, что вызывает такое поведение?
РЕДАКТИРОВАТЬ (07.01.2013): до сих пор не понимаю, почему эти результаты смещены... До сих пор я заметил, что если я создал переменную, установленную на ноль, прямо перед вторым оператором foreach, добавил ее к позициям каждого текстового указателя и увеличил это на 4 (не знаю почему) в конце каждого цикла результаты окрашиваются адекватно. Тем не менее, если я ищу два ключевых слова или более (не имеет значения, имеют ли они одинаковый размер), каждое вхождение первого ключевого слова окрашивается правильно, но хорошо окрашиваются только первые вхождения других ключевых слов. (остальные снова в шахматном порядке) Вот отредактированный код:
rtb.SelectAll();
string allText = rtb.Selection.Text;
string expression = "";
foreach (string word in words)
{
expression = Regex.Escape(word);
Regex regExp = new Regex(expression);
int i = 0;
foreach (Match match in regExp.Matches(allText))
{
TextPointer start = plainText.ContentStart.GetPositionAtOffset(match.Index + i, LogicalDirection.Forward);
TextPointer end = plainText.ContentStart.GetPositionAtOffset(match.Index + match.Length + i, LogicalDirection.Forward);
rtb.Selection.Select(start, end);
rtb.Selection.ApplyPropertyValue(Run.FontWeightProperty, FontWeights.Bold);
rtb.Selection.ApplyPropertyValue(Run.ForegroundProperty, "red");
i += 4; // number found out from trials
}
}