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 that rtb
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);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.