Выделение фразы в 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;
}
Другие вопросы по тегам