2013-04-05 16 views
6

Gibt es eine hübsche Lösung eines GetPositionAtOffset() Äquivalents, das nur Texteinfügepositionen statt aller Symbole zählt?GetPositionAtOffset entspricht nur für Text?

Motivation Beispiel 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: Bis jetzt habe ich "gelöst" es auf diese Weise

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

Wow jemand wirklich wollte nicht die RichTextBox verwendet werden .. danke! – gjvdkamp

Antwort

2

Soweit mir bekannt ist, gibt es nicht. Mein Vorschlag ist, dass Sie zu diesem Zweck Ihre eigene GetPositionAtOffset-Methode erstellen. Sie können überprüfen, welche PointerContext die Textpointer benachbart ist durch die Verwendung:

TextPointer.GetPointerContext(LogicalDirection); 

Um die nächste Textpointer zu erhalten, die zu einem anderen PointerContext-Punkte:

TextPointer.GetNextContextPosition(LogicalDirection); 

Einige Beispielcode ich kürzlich in einem Projekt verwendet, das stellt sicher, dass der Zeigerkontext vom Typ Text ist, indem eine Schleife durchlaufen wird, bis eine gefunden wird. Sie könnten dies in Ihrer Implementierung verwenden und eine Offset-Schritt überspringen, wenn es gefunden wird:

// for a TextPointer start 

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

Hoffentlich Sie Nutzung dieser Informationen treffen können.

+1

Schön. Ich kannte TextPointerContext bis jetzt nicht. –

+0

Ich bin froh zu helfen. Lass es mich wissen, wenn du etwas anderes brauchst! Gute Jagd. – JessMcintosh

0

Konnte keine wirksame Lösung für dieses Problem für eine lange Zeit finden. Das nächste Stück Code funktioniert in meinem Fall mit der höchsten Leistung. Hoffe, es wird auch jemandem helfen.

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