2013-04-05 127 views
6

是否有GetPositionAtOffset()相當於只計算文本插入位置,而不是所有符號的漂亮解決方案?在C#GetPositionAtOffset僅適用於文本?

動機例如:

TextRange GetRange(RichTextBox rtb, int startIndex, int length) { 
    TextPointer startPointer = rtb.Document.ContentStart.GetPositionAtOffset(startIndex); 
    TextPointer endPointer = startPointer.GetPositionAtOffset(length); 
    return new TextRange(startPointer, endPointer); 
} 

編輯:到現在爲止我 「解決」 這種方式

public static TextPointer GetInsertionPositionAtOffset(this TextPointer position, int offset, LogicalDirection direction) 
{ 
    if (!position.IsAtInsertionPosition) position = position.GetNextInsertionPosition(direction); 
    while (offset > 0 && position != null) 
    { 
     position = position.GetNextInsertionPosition(direction); 
     offset--; 
     if (Environment.NewLine.Length == 2 && position != null && position.IsAtLineStartPosition) offset --; 
    } 
    return position; 
} 
+1

哇哇有人真的不希望使用RichTextBox ..謝謝! – gjvdkamp 2014-02-22 09:29:45

回答

2

據我所知,沒有。我的建議是,你爲此創建了自己的GetPositionAtOffset方法。您可以檢查哪些PointerContext的TextPointer毗鄰使用:

TextPointer.GetPointerContext(LogicalDirection); 

獲得下一個TextPointer指向不同的PointerContext:

TextPointer.GetNextContextPosition(LogicalDirection); 

我在最近的一個項目中使用的一些示例代碼,這確保指針上下文是Text類型,循環直到找到一個。你可以在你的實現中使用它,並跳過一個偏移增量,如果它被發現:

// for a TextPointer start 

while (start.GetPointerContext(LogicalDirection.Forward) 
          != TextPointerContext.Text) 
{ 
    start = start.GetNextContextPosition(LogicalDirection.Forward); 
    if (start == null) return; 
} 

希望你可以利用這些信息。

+1

不錯。直到現在還不知道TextPointerContext :) – 2013-09-06 13:42:56

+0

很高興能提供幫助。需要幫助請叫我!好狩獵。 – JessMcintosh 2013-09-06 13:43:58

0

很長一段時間找不到有效的解決方案。 下一段代碼對我來說具有最高的性能。希望它能幫助別人。

TextPointer startPos = rtb.Document.ContentStart.GetPositionAtOffset(searchWordIndex, LogicalDirection.Forward); 
startPos = startPos.CorrectPosition(searchWord, FindDialog.IsCaseSensitive); 
if (startPos != null) 
{ 
    TextPointer endPos = startPos.GetPositionAtOffset(textLength, LogicalDirection.Forward); 
    if (endPos != null) 
    { 
     rtb.Selection.Select(startPos, endPos); 
    } 
} 

public static TextPointer CorrectPosition(this TextPointer position, string word, bool caseSensitive) 
{ 
    TextPointer start = null; 
    while (position != null) 
    { 
     if (position.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.Text) 
     { 
      string textRun = position.GetTextInRun(LogicalDirection.Forward); 

      int indexInRun = textRun.IndexOf(word, caseSensitive ? StringComparison.InvariantCulture : StringComparison.InvariantCultureIgnoreCase); 
      if (indexInRun >= 0) 
      { 
       start = position.GetPositionAtOffset(indexInRun); 
       break; 
      } 
     } 

     position = position.GetNextContextPosition(LogicalDirection.Forward); 
    } 

    return start; }