How to set caret/cursor position in RichTextBox in WPF?
I use the code in MSDN CaretPosition but it seems the cursor can't be set?
// Create a new FlowDocument, and add 3 paragraphs.
FlowDocument flowDoc = new FlowDocument();
flowDoc.Blocks.Add(new Paragraph(new Run("Paragraph 1")));
flowDoc.Blocks.Add(new Paragraph(new Run("Paragraph 2")));
flowDoc.Blocks.Add(new Paragraph(new Run("Paragraph 3")));
// Set the FlowDocument to be the content for a new RichTextBox.
RichTextBox rtb = new RichTextBox(flowDoc);
// Get the current caret position.
TextPointer caretPos = rtb.CaretPosition;
// Set the TextPointer to the end of the current document.
caretPos = caretPos.DocumentEnd;
// Specify the new caret position at the end of the current document.
rtb.CaretPosition = caretPos;
How to set caret/cursor position in RichTextBox in WPF?
Assuming thatrtb
is the name of your RichTextBox, with different Blocks and Inlines, you can set the Caret at the beginning of the document by:
rtb.CaretPosition = rtb.CaretPosition.DocumentStart;
or at its end:
rtb.CaretPosition = rtb.CaretPosition.DocumentEnd;
On the other hand, assuming that you have a specific Paragraph or Block, such as:
Block blk = rtb.Document.Blocks.ElementAt(1);
You can set caret to its start
rtb.CaretPosition = blk.ContentStart;
or its end
rtb.CaretPosition = blk.ContentEnd;
or if you have a specific Inline such as
Run r = ((Paragraph)rtb.Document.Blocks.ElementAt(0)).Inlines.ElementAt(1) as Run;
You can also use
rtb.CaretPosition = r.ContentStart;
rtb.CaretPosition = r.ContentEnd;
Of course, if you are working with Complex paragraph with both right-to-left and left-to-right text, you might need to consider
rtb.CaretPosition = blk.ElementStart;
rtb.CaretPosition = blk.ElementEnd;
Also note different methods implemented in a TextPointer
, which you can use to reach different parts of the document/Blocks/Inlines:
rtb.CaretPosition = rtb.CaretPosition.GetLineStartPosition(0);
rtb.CaretPosition = rtb.CaretPosition.GetPositionAtOffset(2);
See the link for more methods and more information.
At the end, you might want to use BringIntoView
method implemented in a Block or Inline:
blk.BringIntoView();
r.BringIntoView();
and also setting the keyboard focus, to see the blinking of the Caret:
Keyboard.Focus(rtb);
Remember to Set focus so that the cursor will appear in the RichTextBox:
// Create a new FlowDocument, and add 3 paragraphs.
FlowDocument flowDoc = new FlowDocument();
flowDoc.Blocks.Add(new Paragraph(new Run("Paragraph 1")));
flowDoc.Blocks.Add(new Paragraph(new Run("Paragraph 2")));
flowDoc.Blocks.Add(new Paragraph(new Run("Paragraph 3")));
// Set the FlowDocument to be the content for a new RichTextBox.
RichTextBox rtb = new RichTextBox(flowDoc);
//****SET FOCUS****
rtb.Focus();
// Get the current caret position.
TextPointer caretPos = rtb.CaretPosition;
// Set the TextPointer to the end of the current document.
caretPos = caretPos.DocumentEnd;
// Specify the new caret position at the end of the current document.
rtb.CaretPosition = caretPos;
.
In addition to Setting to Document End, You can use GetPositionAtOffset to set caretPos backward / forward
and amount of displacement you want to move:
int displacement = 8;
// Set the TextPointer 8 displacement backward.
caretPos = caretPos.GetPositionAtOffset(displacement, LogicalDirection.Backward);
.
Example, you can paste it to the Constructor of an Empty Window to test:
public RichTbxFlowDocumentTest()
{
InitializeComponent();
// Create a new FlowDocument, and add 3 paragraphs.
FlowDocument flowDoc = new FlowDocument();
flowDoc.Blocks.Add(new Paragraph(new Run("Paragraph 1")));
flowDoc.Blocks.Add(new Paragraph(new Run("Paragraph 2")));
flowDoc.Blocks.Add(new Paragraph(new Run("Paragraph 3")));
// Set the FlowDocument to be the content for a new RichTextBox.
RichTextBox rtb = new RichTextBox(flowDoc);
//Add RichTextBox and Button with setting cursor method to a new StackPanel
StackPanel s = new StackPanel();
Button button = new Button() { Content = "Set Cursor Pos" };
button.Click += (sender, e) =>
{
//SET FOCUS
rtb.Focus();
// Get the current caret position.
TextPointer caretPos = rtb.CaretPosition;
//Set amount of displacement
int displacement = 6;
// Set the TextPointer 6 displacement backward
caretPos = caretPos.GetPositionAtOffset(displacement, LogicalDirection.Backward);
// Specify the new caret position to RichTextBox
rtb.CaretPosition = caretPos;
};
s.Children.Add(button);
s.Children.Add(rtb);
this.Content = s;
}
}
.
Result:
(I move the window in the middle to prevent afterimage)
.
Other Supplement:
If you want to move RichTextBox caret up or down one line, you can see https://social.msdn.microsoft.com/Forums/vstudio/en-US/8c34e7b1-91ed-4b11-979d-d18b28a71f6f/how-do-you-move-richtextbox-caret-up-or-down-one-line?forum=wpf
myRichTextBox.Focus();
EditingCommands.MoveUpByLine.Execute(null, myRichTextBox);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With