Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
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;
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);
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.