2014-02-19 3 views
0

У меня есть TextPointer tp, указывающий на начало фразы, которую я хотел бы выделить с помощью TextRange. Тем не менее этот код:Выделение фразы в FlowDocument

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 + "<"); 

Дает неправильный результат:

фраза: шоколадный мусс, LEN = 18 и длина тр = 15 и tr.text = мусс Chocó <

Я использовал Ниже получить начальное положение фразы в моем документе:

x = tr.Text.IndexOf(phrase); 

Как получить подстроку TextRange данную строку фразу и TextRange для документ?

Следующий ответ показывает MSDN пример кода для поиска слова:

https://stackoverflow.com/a/984836/317033

Однако это не похоже на работу с фразами в моем случае. В документации: http://msdn.microsoft.com/en-us/library/ms598662(v=vs.110).aspx Смещение GetPositionAtOffset включает в себя «символы», которые являются не только видимыми символами. Таким образом, пример кода не работает должным образом, так как вы не можете просто использовать string.IndexOf() с GetPositionAtOffset.

Таким образом, похоже, что ответ будет включать правильный учет несимвольных элементов (символов в документации), которые необходимо включить в смещение. Мой наивный подсчет количества прогонов пробелов фразы не работает.

+0

Фраза распространяется на 3 пробега, если какой-то разрыв между пробегом занимает 1 от длины. * shrug * – Mark

ответ

2

Следующий метод делает то же самое, что и 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; 
} 
+0

спасибо! Это гораздо более чистый путь. – Mark

+0

ПРИМЕЧАНИЕ GetTextRunLength исключает новые строки, как и функция GetTextRun. Вы не можете пересекать линии с этим или TextRange.Text, который включает в себя символы новой строки, будет отличаться от ожидаемой. – Mark