Selection in WPF RichTextBox (SfRichTextBoxAdv)

15 Jul 202117 minutes to read

The SfRichTextBoxAdv supports selecting a portion of the document either through UI interactions by using mouse, touch, keyboard or through supported APIs.
The following sample code demonstrates how to retrieve text position from document using paragraph instance and offset value.

// Gets the first section of the document.
SectionAdv sectionAdv = richTextBoxAdv.Document.Sections[0];
'Gets the first section of the document
Dim sectionAdv As SectionAdv = richTextBoxAdv.Document.Sections(0)
// Gets the first block from the section, which is a paragraph.
ParagraphAdv paragraphAdv = sectionAdv.Blocks[0] as ParagraphAdv;
// Gets the text position of the specified paragraph at offset 24. 
// TextPosition is returned as null, if no such paragraph or offset exists in the document.
TextPosition startPosition = richTextBoxAdv.Document.GetTextPosition(paragraphAdv, 24);
' Gets the first block from the section, which is a paragraph.
Dim paragraphAdv As ParagraphAdv = TryCast(sectionAdv.Blocks(0), ParagraphAdv)
' Gets the text position of the specified paragraph at offset 24. 
' TextPosition is returned as null, if no such paragraph or offset exists in the document.
Dim startPosition As TextPosition = richTextBoxAdv.Document.GetTextPosition(paragraphAdv, 24)
// Gets the third block of a section, which is table.
TableAdv tableAdv = sectionAdv.Blocks[2] as TableAdv;
// Gets the third block from second row second cell of the table, which is paragraph.
ParagraphAdv paragraphAdv = tableAdv.Rows[1].Cells[1].Blocks[2] as ParagraphAdv;
TextPosition position = richTextBoxAdv.Document.GetTextPosition(paragraphAdv, 12);
' Gets the third block of a section, which is table.
Dim tableAdv As TableAdv = TryCast(sectionAdv.Blocks(2), TableAdv)
' Gets the third block from second row second cell of the table, which is paragraph.
Dim paragraphAdv As ParagraphAdv = TryCast(tableAdv.Rows(1).Cells(1).Blocks(2), ParagraphAdv)
Dim position As TextPosition = richTextBoxAdv.Document.GetTextPosition(paragraphAdv, 12)

The following sample code demonstrates how to retrieve text position from document using hierarchical index.

/*
The hierarchical index should be given as "section-index;block-index;offset-in-paragraph"
If block in the index is paragraph, then next value is considered as offset and position is retrieved.
For example "0;0;1" gets text position of Paragraph (first block of first section) at the offset=1.
If block in the index is table, then next value is considered as row index and following value as cell index.
The value after cell is again a block index. Then the same process continues.
"table-index;row-index;cell-index;block-index;"
For example "0;2;1;1;0;21" gets text position of Paragraph at first block of second cell of second row of table (at third block of first section) at the offset=21.
If offset value is followed by "C" which stands for comment, then the comment is retrieved which is followed by block index in comment. Then the process of retrieving paragraph from block index continues.
paragraph-index;offset-in-paragraph;C;block-index;offset-in-paragraph
For example "0;3;16;C;2;6", gets text position of Paragraph at third block of comment (present at offset = 16 in paragraph at third block of first section) at the offset=6.
*/
// Gets the text position from the document based on hierarchical index.
TextPosition position = richTextBoxAdv.Document.GetTextPosition("0;0;24");
/* Here text position returned should be first section's first block (which is paragraph) and offset=24. */
'
'The hierarchical index should be given as "section-index;block-index;offset-in-paragraph"
'If block in the index is paragraph, then next value is considered as offset and position is retrieved.
'For example "0;0;1" gets text position of Paragraph (first block of first section) at the offset=1.
'If block in the index is table, then next value is considered as row index and following value as cell index.
'The value after cell is again a block index. Then the same process continues.
'"table-index;row-index;cell-index;block-index;"
'For example "0;2;1;1;0;21" gets text position of Paragraph at first block of second cell of second row of table (at third block of first section) at the offset=21.
'If offset value is followed by "C" which stands for comment, then the comment is retrieved which is followed by block index in comment. Then the process of retrieving paragraph from block index continues.
'paragraph-index;offset-in-paragraph;C;block-index;offset-in-paragraph
'For example "0;3;16;C;2;6", gets text position of Paragraph at third block of comment (present at offset = 16 in paragraph at third block of first section) at the offset=6.
'

' Gets the text position from the document based on hierarchical index.
Dim position As TextPosition = richTextBoxAdv.Document.GetTextPosition("0;0;24")
' Here text position returned should be first section's first block (which is paragraph) and offset=24.

The following sample code demonstrates how to move selection start and selection end both at a specific text position.

// Makes an empty selection at the specific text position.
richTextBoxAdv.Selection.Select(position, position);
' Makes an empty selection at the specific text position.
richTextBoxAdv.Selection.[Select](position, position)

The following sample code demonstrates how to select a portion of document.

// Retrieves the position of the first paragraph start.
TextPosition startPosition = richTextBoxAdv.Document.GetTextPosition("0;0;0");
// Retrieves the position of the first paragraph at offset=20.
TextPosition endPosition = richTextBoxAdv.Document.GetTextPosition("0;0;20");
// Selects the text positions in forward direction.
richTextBoxAdv.Selection.Select(startPosition, endPosition);
' Retrieves the position of the first paragraph start.
Dim startPosition As TextPosition = richTextBoxAdv.Document.GetTextPosition("0;0;0")
' Retrieves the position of the first paragraph at offset=20.
Dim endPosition As TextPosition = richTextBoxAdv.Document.GetTextPosition("0;0;20")
' Selects the text positions in forward direction.
richTextBoxAdv.Selection.[Select](startPosition, endPosition)
// Selects the text positions in reverse direction.
richTextBoxAdv.Selection.Select(endPosition, startPosition);
' Selects the text positions in reverse direction.
richTextBoxAdv.Selection.[Select](endPosition, startPosition)

NOTE

You can select a text position within a comment with another text position within the same comment only. It is not possible to select a text position within comment with a text position that exists outside of that comment.

Multi Selection

The SfRichTextBoxAdv also supports selecting different portions of the document at a time. The following code example demonstrates how to perform multi selection in SfRichTextBoxAdv.

// Retrieves the position of the first paragraph start.
TextPosition startPosition1 = richTextBoxAdv.Document.GetTextPosition("0;0;0");
// Retrieves the position of the first paragraph at offset=20.
TextPosition endPosition1 = richTextBoxAdv.Document.GetTextPosition("0;0;20");
// Retrieves the position of the third paragraph start.
TextPosition startPosition2 = richTextBoxAdv.Document.GetTextPosition("0;2;0");
// Retrieves the position of the third paragraph at offset=20.
TextPosition endPosition2 = richTextBoxAdv.Document.GetTextPosition("0;2;20");
// Selects the first paragraph and third paragraph at a time, leaving second paragraph.
richTextBoxAdv.Selection.SelectionRanges.Add(startPosition1, endPosition1);
richTextBoxAdv.Selection.SelectionRanges.Add(startPosition2, endPosition2);
' Retrieves the position of the first paragraph start.
Dim startPosition1 As TextPosition = richTextBoxAdv.Document.GetTextPosition("0;0;0")
' Retrieves the position of the first paragraph at offset=20.
Dim endPosition1 As TextPosition = richTextBoxAdv.Document.GetTextPosition("0;0;20")
' Retrieves the position of the third paragraph start.
Dim startPosition2 As TextPosition = richTextBoxAdv.Document.GetTextPosition("0;2;0")
' Retrieves the position of the third paragraph at offset=20.
Dim endPosition2 As TextPosition = richTextBoxAdv.Document.GetTextPosition("0;2;20")
' Selects the first paragraph and third paragraph at a time, leaving second paragraph.
richTextBoxAdv.Selection.SelectionRanges.Add(startPosition1, endPosition1)
richTextBoxAdv.Selection.SelectionRanges.Add(startPosition2, endPosition2)

Apply Formatting for selection

The SfRichTextBoxAdv supports the following format properties that can be applied for selection contents.
Character Format-bold, italic, font size, font family, font color, highlight color, underline, strikethrough, subscript, and superscript.
Paragraph Format-before and after spacing, first line, left and right indenting, text justification, line spacing, and multilevel list.
Selection Format-page size and page margin.
The following sample code demonstrates how to apply subscript format for the selected content.

// Applies subscript format for the selected text contents.
richTextBoxAdv.Selection.CharacterFormat.BaselineAlignment = Syncfusion.Windows.Controls.RichTextBoxAdv.BaselineAlignment.Subscript;
' Applies subscript format for the selected text contents.
richTextBoxAdv.Selection.CharacterFormat.BaselineAlignment = Syncfusion.Windows.Controls.RichTextBoxAdv.BaselineAlignment.Subscript

The following sample code demonstrates how to apply after spacing for the selected paragraphs.

// Applies after spacing for the selected paragraphs.
richTextBoxAdv.Selection.ParagraphFormat.AfterSpacing = 24;
' Applies after spacing for the selected paragraphs.
richTextBoxAdv.Selection.ParagraphFormat.AfterSpacing = 24

The following sample code demonstrates how to apply page margin for the selected sections.

// Applies page margin for the selected sections.
richTextBoxAdv.Selection.SectionFormat.PageMargin = new Thickness(96, 48, 96, 48);
' Applies page margin for the selected sections.
richTextBoxAdv.Selection.SectionFormat.PageMargin = New Thickness(96, 48, 96, 48)

Binding Selection format properties

The SfRichTextBoxAdv provides support to bind the rich-text format options of selection content.
The following code sample demonstrates how to bind the bold format option of SfRichTextBoxAdv.

<!-- Binds the toggle button to Selection bold character format -->
<ToggleButton x:Name="toggleButton" Content="Bold" IsChecked="{Binding Path=Selection.CharacterFormat.Bold, Mode=TwoWay, ElementName=richTextBoxAdv}" />
// Initializes the new binding for toggle bold.
Binding binding = new Binding() { Source = richTextBoxAdv, Path = new PropertyPath("Selection.CharacterFormat.Bold"), Mode = BindingMode.TwoWay };

// Binds the IsChecked property to Selection.CharacterFormat.Bold property of RichTextBoxAdv.
toggleButton.SetBinding(ToggleButton.IsCheckedProperty, binding);
' Initializes the new binding for toggle bold.
Dim binding As New Binding() With { _
	Key .Source = richTextBoxAdv, _
	Key .Path = New PropertyPath("Selection.CharacterFormat.Bold"), _
	Key .Mode = BindingMode.TwoWay _
}

' Binds the IsChecked property to Selection.CharacterFormat.Bold property of RichTextBoxAdv.
toggleButton.SetBinding(ToggleButton.IsCheckedProperty, binding)

The following code sample demonstrates how to bind the bold format option of SfRichTextBoxAdv.

<!—Binds IsChecked property of toggle button to Selection text alignment paragraph format -->
<ToggleButton x:Name="toggleButton" Content="Left" IsChecked="{Binding ElementName=richTextBoxAdv,Path=Selection.ParagraphFormat.TextAlignment,Converter={StaticResource LeftAlignmentToggleConverter}}"/>
//Initializes the new binding for toggle text alignment property as left.
Binding binding = new Binding() { Source = richTextBoxAdv, Path = new PropertyPath("Selection.ParagraphFormat.TextAlignment"), Mode = BindingMode.TwoWay, Converter = new LeftAlignmentToggleConverter() };

//Binds the IsChecked property to Selection.ParagraphFormat.TextAlignment property of RichTextBoxAdv.
toggleButton.SetBinding(ToggleButton.IsCheckedProperty, binding);
'Initializes the new binding for toggle text alignment property as left.
Dim binding As New Binding() With { _
	Key .Source = richTextBoxAdv, _
	Key .Path = New PropertyPath("Selection.ParagraphFormat.TextAlignment"), _
	Key .Mode = BindingMode.TwoWay, _
	Key .Converter = New LeftAlignmentToggleConverter() _
}

'Binds the IsChecked property to Selection.ParagraphFormat.TextAlignment property of RichTextBoxAdv.
toggleButton.SetBinding(ToggleButton.IsCheckedProperty, binding)

Keyboard shortcuts to perform selection

The following keyboard shortcuts are supported by SfRichTextBoxAdv for navigation.

Navigation Shortcut
Description
Right Arrow
Navigates to one position forward.
Left Arrow
Navigates to one position backward.
Down Arrow
Navigates to the same position at next line.
Up Arrow
Navigates to the same position at previous line.
Home
Navigates to start of the current line.
End
Navigates to end of the current line.
CTRL + Home
Navigates to the document start position.
CTRL + End
Navigates to the document end position.
CTRL + Right
Navigates to the next word start position.
CTRL + Left
Navigates to the current word start position.
CTRL + Down
Navigates to the next paragraph start position.
CTRL + Up
Navigates to the current paragraph start position.

The following keyboard shortcuts are supported by SfRichTextBoxAdv for selection.

Selection Shortcut
Description
CTRL + Right Arrow
Extends selection to one position forward.
CTRL + Left Arrow
Extends selection to one position backward.
CTRL + Down Arrow
Extends selection to the same position at next line.
CTRL + Up Arrow
Extends selection to the same position at previous line.
SHIFT + Home
Extends selection to start of the current line.
SHIFT + End
Extends selection to end of the current line.
CTRL + SHIFT + Home
Extends selection to the document start position.
CTRL + SHIFT + End
Extends selection to the document end position.
CTRL + SHIFT + Right
Extends selection to the current word end position.
CTRL + SHIFT + Left
Extends selection to the current word start position.
CTRL + SHIFT + Down
Extends selection to the current paragraph end position.
CTRL + SHIFT + Up
Extends selection to the current paragraph start position.
CTRL + A
Selects the entire document.

How to show blinking cursor and selection highlight even when the control lost focus

The SfRichTextBoxAdv control allows you to show the blinking cursor and selection highlight even when the control doesn’t have focus. You can choose any one of the following selection visibility options:

  • None - Don’t display neither caret nor selection highlight when the RichTextBox control doesn’t have focus.

  • ShowCaret - Displays the caret (blinking cursor) when the RichTextBox control doesn’t have focus.

  • ShowSelection - Displays the selection highlight when the RichTextBox control doesn’t have focus.

The following code example demonstrates how to display the selection highlight even when the RichTextBox control doesn’t have focus.

<RichTextBoxAdv:SfRichTextBoxAdv x:Name="richTextBoxAdv" LostFocusBehavior="ShowSelection"  xmlns:RichTextBoxAdv="clr-namespace:Syncfusion.Windows.Controls.RichTextBoxAdv;assembly=Syncfusion.SfRichTextBoxAdv.Wpf" />
// Initializes a new instance of RichTextBoxAdv.
SfRichTextBoxAdv richTextBoxAdv = new SfRichTextBoxAdv();
// Displays the selection highlight when the RichTextBox control doesn't have focus.
richTextBoxAdv.LostFocusBehavior = LostFocusBehavior.ShowSelection;
' Initializes a new instance of RichTextBoxAdv.
Dim richTextBoxAdv As New SfRichTextBoxAdv()

' Displays the selection highlight when the RichTextBox control doesn't have focus.
richTextBoxAdv.LostFocusBehavior = LostFocusBehavior.ShowSelection

NOTE

This API is supported starting from release version v17.4.0.X.

How to determine the editing context type

The SfRichTextBoxAdv control allows you to know the editing context type based on the selected content. The following are the editing context types:

  • Text - Denotes that the editing context is text

  • Image - Denotes that the editing context is image

  • Table - Denotes that the editing context is table

The following code example demonstrates how to determine the editing context type based on the selection.

// Initializes a new instance of RichTextBoxAdv.
SfRichTextBoxAdv richTextBoxAdv = new SfRichTextBoxAdv();
if (richTextBoxAdv.Selection.EditingContext.Type == EditingContextType.Text)
 {
 }
' Initializes a new instance of RichTextBoxAdv.
Dim richTextBoxAdv As New SfRichTextBoxAdv()
If (richTextBoxAdv.Selection.EditingContext.Type == EditingContextType.Text) Then
End If

How to delete the selected content

The SfRichTextBoxAdv supports deleting the selected portion of the document either through UI command, keyboard or through supported APIs.

The following code sample demonstrates how to delete the selected portion of the document using the DeleteKeyCommand.

<!-- Binds button to the DeleteKeyCommand -->
<Button Content="Delete" Command="RichTextBoxAdv:SfRichTextBoxAdv.DeleteKeyCommand" CommandTarget="{Binding ElementName=richTextBoxAdv}"/>

The following code sample demonstrates how to delete the selected portion of the document using the Delete method. This method is valid only when the selection is non-empty, and it returns true if the selected content is deleted. Otherwise false.

//Deletes the selected content in SfRichTextBoxAdv control.
bool isDeleted = richTextBoxAdv.Selection.Delete();
Dim isDeleted As Boolean = richTextBoxAdv.Selection.Delete()

NOTE

This API is supported starting from release version v18.2.0.X.
You can refer to our WPF RichTextBox feature tour page for its groundbreaking feature representations.You can also explore our WPF RichTextBox example to knows how to render and configure the editing tools.