2013-04-05 126 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; }