TextPointer Class

TextPointer Class

[ This article is for Windows Phone 8 developers. If you’re developing for Windows 10, see the latest documentation. ]

Represents a position within a RichTextBox.


Namespace:  System.Windows.Documents
Assembly:  System.Windows (in System.Windows.dll)

public class TextPointer

The TextPointer type exposes the following members.

Public propertyIsAtInsertionPositionGets a value that indicates whether the current position is an insertion.
Public propertyLogicalDirectionGets the logical direction associated with the current position, which is used to disambiguate content associated with the current position.
Public propertyParentGets the logical parent that contains the current position.

Public methodCompareToPerforms an ordinal comparison between the positions specified by the current TextPointer and a second specified TextPointer.
Public methodEquals(Object)Determines whether the specified Object is equal to the current Object. (Inherited from Object.)
Protected methodFinalizeAllows an object to try to free resources and perform other cleanup operations before the Object is reclaimed by garbage collection. (Inherited from Object.)
Public methodGetCharacterRectReturns a bounding box for content that borders the current TextPointer in the specified logical direction.
Public methodGetHashCodeServes as a hash function for a particular type. (Inherited from Object.)
Public methodGetNextInsertionPositionReturns a TextPointer to the next insertion position in the specified logical direction.
Public methodGetPositionAtOffsetReturns a TextPointer to the position indicated by the specified offset, in symbols, from the beginning of the current TextPointer and in the specified direction.
Public methodGetTypeGets the Type of the current instance. (Inherited from Object.)
Protected methodMemberwiseCloneCreates a shallow copy of the current Object. (Inherited from Object.)
Public methodToStringReturns a string that represents the current object. (Inherited from Object.)

The TextPointer class is intended to facilitate traversal and manipulation of content in a RichTextBox. The TextPointer class introduces the following terminology:

  • Position - A TextPointer that points to a location in the content of a RichTextBox. A position either occurs between characters in the content, or between content element tags that define structure for the content.

  • Current Position - The position indicated by the current TextPointer. Many of the operations that can be performed with a TextPointer are relative to the current TextPointer position. Therefore, a position indicated by a TextPointer is typically referred to as the current position.

  • Insertion Position - A position where new content may be added without breaking any semantic rules for the associated content. In practice, an insertion position is anywhere in content where a caret may be positioned. An example of a valid TextPointer position that is not an insertion position is the position between two adjacent Paragraph tags (that is, between the closing tag of the preceding paragraph and the opening tag of the next paragraph).

  • Symbol - For TextPointer operations, any of the following is considered to be a symbol:

    • An opening or closing tag for a TextElement element.

    • A UIElement element contained within an InlineUIContainer. Note that a UIElement is always counted as exactly one symbol. Any additional content or elements contained by the UIElement are not considered symbols.

    • Each 16-bit Unicode character inside of a text Run element.

  • Text Container - The element that forms the border for the content. The position indicated by a TextPointer always occurs within a text container. Currently, a text container can only be a RichTextBox. Typically, operations between TextPointer instances in different text containers are not supported.

Some of the operations that TextPointer facilitates include the following:

  • Performing an ordinal comparison of the current position with a second specified position. For more information, see the CompareTo method.

  • Get the TextElement or the RichTextBox that scopes the specified position. For more information, see the Parent property.

  • Translating between TextPointer positions and symbol offsets into content. For more information, see the GetPositionAtOffset method.

  • Performing visual hit testing by translating between a TextPointer position and a Point representing relative coordinates.

  • Finding a nearby insertion position, or checking whether the current position is an insertion position. For more information, see the GetNextInsertionPosition method and the IsAtInsertionPosition property.

The position and LogicalDirection indicated by a TextPointer object are immutable. When content is edited or modified, the position indicated by a TextPointer does not change relative to the surrounding text. Instead, the offset of that position from the beginning of content is adjusted correspondingly to reflect the new relative position in content. For example, a TextPointer that indicates a position at the beginning of a paragraph continues to point to the beginning of that paragraph even when content is inserted or deleted before or after the paragraph.

The TextPointer class does not provide any public constructors. An instance of TextPointer is created by using properties or methods of other objects (including other TextPointer objects). The following list provides a few examples of methods and properties that create and return a TextPointer. This list is not exhaustive:

The following code example highlights the first word and underlines the last word in the sentence that you type in the RichTextBox. In this example, a space character is used as the word boundary. The example will also identify if the RichTextBox is empty.

<Canvas x:Name="LayoutRoot" Background="Transparent">
    <RichTextBox x:Name="MyRTB1" Width="301" Canvas.Left="0" Canvas.Top="41" />

    <Button x:Name="MyButton" Content="Click here" Click="MyButton_Click" Canvas.Left="0" Canvas.Top="71" />
    <TextBlock x:Name="MyTBl" Canvas.Left="83" Canvas.Top="71" Height="23"  Width="218" />
    <TextBlock Canvas.Left="0" Canvas.Top="12" Height="23" Name="textBlock1" Text="Enter a sentence." Width="225" />

//This method underlines the last word in a RichTextBox
public void UnderlineLastWord()
    TextPointer EndofContent = MyRTB1.ContentEnd.GetNextInsertionPosition(LogicalDirection.Backward);
    TextPointer currentPointer = EndofContent.GetNextInsertionPosition(LogicalDirection.Backward);

    if (currentPointer == null)

    string currentChar = GetCurrentChar(MyRTB1, currentPointer, LogicalDirection.Backward);

    while (currentChar != " " && currentChar != "")
        currentPointer = currentPointer.GetNextInsertionPosition(LogicalDirection.Backward);
        currentChar = GetCurrentChar(MyRTB1, currentPointer, LogicalDirection.Backward);

    if (currentChar == " ")
        MyRTB1.Selection.Select(currentPointer.GetNextInsertionPosition(LogicalDirection.Forward), EndofContent);
        MyRTB1.Selection.Select(currentPointer, EndofContent);

    MyRTB1.Selection.ApplyPropertyValue(Run.TextDecorationsProperty, TextDecorations.Underline);

private string GetCurrentChar(RichTextBox RTB, TextPointer pointer, LogicalDirection direction)
    TextPointer nextPointer = pointer.GetNextInsertionPosition(direction);
    if (nextPointer != null)
        RTB.Selection.Select(pointer, nextPointer);
        if (RTB.Selection.Text.Length != 0)
            return RTB.Selection.Text[0].ToString();
    return "";

//This method returns true if the RichTextBox is empty.
public bool isRichTextBoxEmpty()
    TextPointer startPointer = MyRTB1.ContentStart.GetNextInsertionPosition(LogicalDirection.Forward);
    TextPointer endPointer = MyRTB1.ContentEnd.GetNextInsertionPosition(LogicalDirection.Backward);
    if (startPointer.CompareTo(endPointer) == 0)
        return true;
        return false;

//This method highlights the first word in the RichTextBox
public void HighlightFirstWord()
    TextPointer StartofContent = MyRTB1.ContentStart;
    TextPointer currentPointer = StartofContent.GetNextInsertionPosition(LogicalDirection.Forward);

    if (currentPointer == null)

    string currentChar = GetCurrentChar(MyRTB1, currentPointer, LogicalDirection.Forward);

    while (currentChar != " " && currentChar != "")
        currentPointer = currentPointer.GetNextInsertionPosition(LogicalDirection.Forward);
        currentChar = GetCurrentChar(MyRTB1, currentPointer, LogicalDirection.Forward);

    Rect StartRect = StartofContent.GetCharacterRect(LogicalDirection.Forward);
    Rect EndRect = currentPointer.GetCharacterRect(LogicalDirection.Forward);


private Rectangle CreateHighlightRectangle(Rect bounds)
    Rectangle r = new Rectangle();
    r.Fill = new SolidColorBrush(Color.FromArgb(75, 0, 0, 200));
    r.Stroke = new SolidColorBrush(Color.FromArgb(230, 0, 0, 254));
    r.StrokeThickness = 1;
    r.Width = bounds.Width;
    r.Height = bounds.Height;
    Canvas.SetLeft(r, bounds.Left);
    Canvas.SetTop(r, bounds.Top + 41);


    return r;

private void MyButton_Click(object sender, RoutedEventArgs e)
    if (isRichTextBoxEmpty())
        MyTBl.Text = "RichTextBox is empty";
        MyTBl.Text = "";


Windows Phone OS

Supported in: 8.1, 8.0, 7.1

Windows Phone

Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.

© 2017 Microsoft