GetPositionAtOffset equivalent for text only?

倾然丶 夕夏残阳落幕 提交于 2019-12-07 04:00:56

问题


Is there a pretty solution of a GetPositionAtOffset() equivalent which only counts text insertion positions instead of all symbols?

Motivation example in 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);
}

Edit: Until now i "solved" it this way

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:


As far as I'm aware, there isn't. My suggestion is that you create your own GetPositionAtOffset method for this purpose. You can check which PointerContext the TextPointer is adjacent to by using:

TextPointer.GetPointerContext(LogicalDirection);

To get the next TextPointer which points to a different PointerContext:

TextPointer.GetNextContextPosition(LogicalDirection);

Some sample code I used in a recent project, this makes sure that the pointer context is of type Text, by looping until one is found. You could use this in your implementation and skip an offset increment if it is found:

// for a TextPointer start

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

Hopefully you can make use of this information.




回答2:


Could not find effective solution to this problem for a long time. Next piece of code works in my case with the highest performance. Hope it will help somebody as well.

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


来源:https://stackoverflow.com/questions/15839031/getpositionatoffset-equivalent-for-text-only

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!