New to Telerik UI for WPF? Download free 30-day trial

Positioning

The positioning feature in RadRichTextBox is used to navigate through document's content and to get information about the document's elements at a specific position. The RadDocument uses the positioning to track the movement of the caret and to control the selection.

Overview

The positioning is implemented via the DocumentPosition class. This class can be used by the developer to programmatically control the positioning or the selection. DocumentPosition offers methods, such as MoveToNextWordStart(), MoveToPreviousWordStart(), MoveToCurrentLineStart/End() and so on, which will navigate to the given document element. In order to get information about the element at a given position, you can use several methods such as GetCurrentSpanBox(), GetCurrentParagraphBox(), GetCurrentSectionBox() and so on which will return the LayoutBox of an element. Another option is to use directly the methods returning the specific document element - GetCurrentSpan(), GetCurrentParagraph(), GetCurrentTable() etc.

DocumentPosition also redefines equality and comparison operators for more convenience, when you should find whether the DocumentPosition is before or after another position in the natural flow of the document. By default, RadRichTextBox moves Document.CaretPosition using the arrow keys or on a mouse click. DocumentPosition can also be obtained by giving the coordinates of a point in the document using the method DocumentPosition.SetPosition().

You can manage the caret position for a specific RadDocument by either accessing its CaretPosition property, which is of type DocumentPosition, or by creating a new instance of the DocumentPosition class and associating it with the desired RadDocument.

When using the CaretPosition property you are directly managing the caret position in the RadDocument. By using the DocumentPosition class, you can create instances of several positions inside the document without changing the current caret position.

CaretPosition property

This property enables you to manage the position of the caret inside the document and to obtain information about its location and the elements it currently resides at. Here is an example of how to use the CaretPosition property to get the current word.

Getting the word on the caret position

string currentSpanText = this.radRichTextBox.Document.CaretPosition.GetCurrentSpan().Text; 
Dim currentSpanText As String = Me.radRichTextBox.Document.CaretPosition.GetCurrentSpan().Text 

CaretWidthScaleFactor property

The RadRichTextBox control exposes the CaretWidthScaleFactor property, which will allow you to customize the width of the caret.

Setting the CaretWidthScaleFactor property

this.radRichTextBox.CaretWidthScaleFactor = 10; 
Me.radRichTextBox.CaretWidthScaleFactor = 10 

DocumentPosition Class

An alternative of using the CaretPosition property is to create an instance of the DocumentPosition class. Here is the same example from the previous chapter done with an instance of the DocumentPosition class.

When instantiated in such a way, the position will be at the start of the document, so the result will be the first word in the text. The position of the instance won't be affected by the UI. To change it, you have to use the API of the DocumentPosition class.

Getting the word on the caret using the DocumentPosition class

DocumentPosition position = new DocumentPosition(this.radRichTextBox.Document); 
string currentSpanText = position.GetCurrentSpan().Text; 
Dim position As New DocumentPosition(Me.radRichTextBox.Document) 
Dim currentSpanText As String = position.GetCurrentSpan().Text 

To set selection range in RadRichTextBox, you can use the DocumentPosition class. You can read more about this in the Selection help article.

Tracking Positions

When you need to ensure that the position is kept between the same characters, no matter the modifications users can do on the document content, you can instantiate the DocumentPosition object using one of the constructors accepting a boolean value. This boolean value indicates whether the position should track the changes in the document and move accordingly so it can be located on the same position in the word.

DocumentPosition created with any of the constructors accepting the boolean trackDocumentChangeEvents parameter set to true moves automatically when the document is edited before the position (just like the caret position).

Positions created in such a way could be explicitly disposed to avoid preserving them too much in memory.

Determine The Type of Element The Position Is At

The DocumentPosition class offers different properties allowing you to determine where the position is located. For example, you can check whether the position is at the start of the document or at its end. Similarly, you can obtain information whether the position is inside table. Here is a list of these properties:

  • IsPositionAtDocumentEnd
  • IsPositionAtDocumentStart
  • IsPositionAtParagraphEnd
  • IsPositionAtParagraphStart
  • IsPositionAtTableCellEnd
  • IsPositionAtTableCellStart
  • IsPositionAtTableRowStart
  • IsPositionInsideTable

There is also a Location property holding information about where in the layout the position is situated.

Access Document Element from Caret Position

You can use the methods of the DocumentPosition class to get the document element at the specific position. The following list shows the methods which can be used.

  • GetCurrentInline()
  • GetCurrentParagraph()
  • GetCurrentSpan()
  • GetCurrentTable()
  • GetCurrentTableCell()
  • GetCurrentTableRow()
  • GetNextInline()
  • GetNextSpan()
  • GetPreviousInline()

In addition to the above-mentioned methods, DocumentPosition exposes also GetCurrent[document element]Box methods returning objects of type LayoutBox, which can be used to get the relevant layout information about a document element. To get the element from the layout box, you can use the AssociatedDocumentElement property.

In the different implementations of the LayoutBox class (examples: ParagraphLayoutBox, SectionLayoutBox, etc.) there are also more specific properties that allow you to easily get the associated document element without casting it from the base DocumentElement class. For example, the GetCurrentParagraphBox() method returns an object of type ParagraphLayoutBox which has AssociatedParagraph property. And the GetCurrentSectionBox() returns SectionLayoutBox which has AssociatedSection property. This rule applies to all LayoutBox elements (also TableLayoutBox, SpanLayoutBox, etc.).

Getting the Paragraph on the caret position

DocumentPosition documentPosition = radRichTextBox.Document.CaretPosition; 
Paragraph paragraph = documentPosition.GetCurrentParagraph(); 
Dim documentPosition As DocumentPosition = radRichTextBox.Document.CaretPosition 
Dim paragraph As Paragraph = documentPosition.GetCurrentParagraph() 

Getting the Inline on the caret position

DocumentPosition documentPosition = radRichTextBox.Document.CaretPosition; 
Inline inline = documentPosition.GetCurrentInline(); 
Dim documentPosition As DocumentPosition = radRichTextBox.Document.CaretPosition 
Dim inline As Inline = documentPosition.GetCurrentInline() 

To get the word on the document position, you can use the GetCurrentWord() method.

Getting the word on the caret position

DocumentPosition documentPosition = radRichTextBox.Document.CaretPosition; 
string word = documentPosition.GetCurrentWord();     
Dim documentPosition As DocumentPosition = radRichTextBox.Document.CaretPosition 
Dim word As String = documentPosition.GetCurrentWord() 

If the searched document element (paragraph, span, table, etc.) cannot be found on the caret position, the corresponding method will return null.

Convert Between DocumentPosition And Screen Position

You can use the ActiveDocumentPresenter of RadRichTextBox to convert a screen position to DocumentPosition and vice versa. The ActiveDocumentPresenter expose couple methods which can be used.

  • GetDocumentPositionFromViewPoint()—The method accepts an argument of type System.Windows.Point and returns an instance of type DocumentPosition.

    Screen position to DocumentPosition conversion

        Point position = GetMousePosition(); 
        DocumentPosition documentPosition = radRichTextBox.ActiveEditorPresenter.GetDocumentPositionFromViewPoint(position); 
    
        Dim position As Point = GetMousePosition() 
        Dim documentPosition As DocumentPosition = radRichTextBox.ActiveEditorPresenter.GetDocumentPositionFromViewPoint(position) 
    
  • GetViewPointFromDocumentPosition()—The method accepts an argument of type DocumentPosition and returns an instance of type System.Windows.Point.

    DocumentPosition to screen position conversion

        DocumentPosition documentPosition = radRichTextBox.Document.CaretPosition; 
        Point position = radRichTextBox.ActiveEditorPresenter.GetViewPointFromDocumentPosition(documentPosition); 
    
        Dim documentPosition As DocumentPosition = radRichTextBox.Document.CaretPosition 
        Dim position As Point = radRichTextBox.ActiveEditorPresenter.GetViewPointFromDocumentPosition(documentPosition) 
    

Events

There are several events that you can use to track changes in the position.

  • LocationChanging—Occurs before changing the coordinates of a position. For the caret position, this can be also achieved by typing, using the arrows keys or by clicking somewhere in the document.
  • LocationChanged—Occurs when changing the coordinates of a position. For the caret position, this can be also achieved by typing, using the arrows keys or by clicking somewhere in the document.

  • PositionChanging—Occurs before the position is moved. For the caret position, this can be also achieved using the arrows keys or by clicking somewhere in the document.

  • PositionChanged—Occurs when the position is moved. For the caret position, this can be also achieved using the arrows keys or by clicking somewhere in the document.

The following example shows how you can change the background of a Table object once the caret is positioned inside a Table.

Using DocumentPosition events

private void CaretPosition_LocationChanged(object sender, EventArgs e) 
{ 
    if (this.radRichTextBox.Document.CaretPosition.IsPositionInsideTable) 
    { 
        Table table = this.radRichTextBox.Document.CaretPosition.GetCurrentTable(); 
        table.Background = Colors.Red; 
    } 
} 
Private Sub CaretPosition_LocationChanged(ByVal sender As Object, ByVal e As EventArgs) 
    If Me.radRichTextBox.Document.CaretPosition.IsPositionInsideTable Then 
        Dim table As Table = Me.radRichTextBox.Document.CaretPosition.GetCurrentTable() 
        table.Background = Colors.Red 
    End If 
End Sub 

See Also

In this article