在WPF中设置RichTextBox的插入符/光标位置

13

如何在WPF的RichTextBox中设置插入符/光标位置?

我使用MSDN CaretPosition中的代码,但似乎无法设置光标?

// 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;
2个回答

24

如何在WPF中设置RichTextBox中的插入符/光标位置?

假设rtb是您的RichTextBox的名称,且具有不同的Blocks和Inlines,您可以通过以下方式将Caret设置为文档开头:

rtb.CaretPosition = rtb.CaretPosition.DocumentStart;

或者在它的结尾处:

rtb.CaretPosition = rtb.CaretPosition.DocumentEnd;

另一方面,假设您有一个特定的段落或块,例如:

Block blk = rtb.Document.Blocks.ElementAt(1);
您可以将插入符设置为其开头。
rtb.CaretPosition = blk.ContentStart;

或它的结束

rtb.CaretPosition = blk.ContentEnd;

或者如果您有特定的内联,例如

Run r = ((Paragraph)rtb.Document.Blocks.ElementAt(0)).Inlines.ElementAt(1) as Run;
您也可以使用。
rtb.CaretPosition = r.ContentStart;
rtb.CaretPosition = r.ContentEnd;

当然,如果您正在处理既包含从右到左又包含从左到右文字的复杂段落时,您可能需要考虑

rtb.CaretPosition = blk.ElementStart;
rtb.CaretPosition = blk.ElementEnd;

还要注意在TextPointer中实现的不同方法,您可以使用这些方法来访问文档/块/内联的不同部分:

rtb.CaretPosition = rtb.CaretPosition.GetLineStartPosition(0);
rtb.CaretPosition = rtb.CaretPosition.GetPositionAtOffset(2);
请查看链接获取更多方法和更多信息。
最后,您可能想要使用在块或内联中实现的BringIntoView方法:
blk.BringIntoView();
r.BringIntoView();

并设置键盘焦点,以查看插入符号的闪烁:

Keyboard.Focus(rtb);

3

请记得设置焦点,这样光标才会出现在 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;

除了将设置移动到文档结尾外,您还可以使用GetPositionAtOffset来设置caretPos的向前或向后以及您想要移动的位移量:

int displacement = 8;

// Set the TextPointer 8 displacement backward.
caretPos = caretPos.GetPositionAtOffset(displacement, LogicalDirection.Backward);

例如,您可以将其粘贴到空窗口的构造器中进行测试:

    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;
    }
}

结果:

(我将窗口移到中间,以防止残影)

输入图片描述

.

其他补充:

如果要将RichTextBox插入符上下移动一行,请参见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);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接