7

是否有一个相当好的解决方案GetPositionAtOffset(),它只计算文本插入位置而不是所有符号?

C# 中的动机示例:

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;
}
4

2 回答 2

2

据我所知,没有。我的建议是您为此目的创建自己的 GetPositionAtOffset 方法。您可以使用以下方法检查 TextPointer 与哪个 PointerContext 相邻:

TextPointer.GetPointerContext(LogicalDirection);

要获取指向不同 PointerContext 的下一个 TextPointer:

TextPointer.GetNextContextPosition(LogicalDirection);

我在最近的一个项目中使用了一些示例代码,这通过循环直到找到一个来确保指针上下文是文本类型。您可以在您的实现中使用它并在找到时跳过偏移增量:

// for a TextPointer start

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

希望您可以利用这些信息。

于 2013-09-06T09:02:00.187 回答
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; }
于 2014-11-14T15:54:07.797 回答