Positioning
The positioning feature in the RadRichTextEditor 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.
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 MoveToNextWord(), MoveToPreviousWord(), 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, RadRichTextEditor moves Document.CaretPosition using arrow keys or on 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.
string currentSpanText = this.radRichTextEditor1.Document.CaretPosition.GetCurrentSpanBox().Text;
Dim currentSpanText As String = Me.radRichTextEditor1.Document.CaretPosition.GetCurrentSpanBox().Text
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.
Telerik.WinForms.Documents.DocumentPosition position = new Telerik.WinForms.Documents.DocumentPosition(this.radRichTextEditor1.Document);
string currentSpanText1 = position.GetCurrentSpanBox().Text;
Dim position As New Telerik.WinForms.Documents.DocumentPosition(Me.radRichTextEditor1.Document)
Dim currentSpanText1 As String = position.GetCurrentSpanBox().Text
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 = this.radRichTextEditor1.Document.CaretPosition;
Paragraph paragraph = documentPosition.GetCurrentParagraph();
Dim documentPosition As DocumentPosition = Me.radRichTextEditor1.Document.CaretPosition()
Dim paragraph As Paragraph = documentPosition.GetCurrentParagraph()
Getting the Inline on the caret position
documentPosition = this.radRichTextEditor1.Document.CaretPosition;
Inline inline = documentPosition.GetCurrentInline();
documentPosition = Me.radRichTextEditor1.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 = this.radRichTextEditor1.Document.CaretPosition;
string word = documentPosition.GetCurrentWord();
documentPosition = Me.radRichTextEditor1.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 ActiveEditorPresenter of RadRichTextEditor to convert a screen position to DocumentPosition and vice versa. The ActiveEditorPresenter exposes a couple of 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 = this.radRichTextEditor1.RichTextBoxElement.ActiveEditorPresenter.GetDocumentPositionFromViewPoint(position);
Dim position As Point = GetMousePosition()
Dim documentPosition As DocumentPosition = Me.radRichTextEditor1.RichTextBoxElement.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 = this.radRichTextEditor1.Document.CaretPosition;
position = this.radRichTextEditor1.RichTextBoxElement.ActiveEditorPresenter.GetViewPointFromDocumentPosition(documentPosition);
documentPosition = Me.radRichTextEditor1.Document.CaretPosition
position = Me.radRichTextEditor1.RichTextBoxElement.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.radRichTextEditor1.Document.CaretPosition.IsPositionInsideTable)
{
Table table = this.radRichTextEditor1.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