Выделение фразы в FlowDocument
У меня есть TextPointer tp, указывающий на начало фразы, которую я хотел бы выделить с помощью TextRange. Однако этот код:
TextRange tr = new TextRange(tp, tp.GetPositionAtOffset(phrase.Length));
Debug.WriteLine("phrase:" + phrase + ", len=" + phrase.Length + " and tr length=" + tr.Text.Length + " and tr.text=" + tr.Text + "<");
Выдает неправильный вывод:
фраза: мусс с шоколадом, длина =18 и длина tr =15 и текст tr.text= мусс с шоколадом<
Я использовал следующее, чтобы получить начальное местоположение фразы в моем документе:
x = tr.Text.IndexOf(phrase);
Как получить подстроку TextRange, заданную строковую фразу и TextRange для документа?
Следующий ответ показывает пример кода MSDN для поиска слова:
/questions/43369217/kak-najti-textrange-v-richtextbox-mezhdu-dvumya-textpointers/43369224#43369224
Однако это не похоже на работу с фразами в моем случае. Согласно документации: http://msdn.microsoft.com/en-us/library/ms598662(v=vs.110).aspx Смещение GetPositionAtOffset включает "символы", которые не являются только видимыми символами. Таким образом, пример кода также не работает должным образом, так как вы не можете просто использовать string.IndexOf() с GetPositionAtOffset.
Таким образом, похоже, что ответ будет включать правильный учет не символьных элементов (символов в документации), которые должны быть включены в смещение. Мой наивный подсчет количества запусков фразы spans не работает.
1 ответ
Следующий метод сделать так же, как GetPositionAtOffset
но считайте только текстовые символы.
TextPointer GetTextPositionAtOffset(TextPointer position, int characterCount)
{
while (position != null)
{
if (position.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.Text)
{
int count = position.GetTextRunLength(LogicalDirection.Forward);
if (characterCount <= count)
{
return position.GetPositionAtOffset(characterCount);
}
characterCount -= count;
}
TextPointer nextContextPosition = position.GetNextContextPosition(LogicalDirection.Forward);
if (nextContextPosition == null)
return position;
position = nextContextPosition;
}
return position;
}