简体   繁体   English

如何在RichTextBox中的当前行末尾设置插入符位置

[英]How To Set Caret Position At The End Of Current Line In A RichTextBox

I'm trying to place the caret of a RichTextBox at the end of the current line it's in. The .CaretPosition attribute is a big change from just using the simple .CaretIndex attribute of a regular TextBox . 我正在尝试将RichTextBox的插入符号放置在当前行的.CaretPosition属性与仅使用常规TextBox的简单.CaretIndex属性相比有很大的变化。

To tackle this issue, I've made my own User-Control which is just a RichTextBox that has most of the properties/methods a TextBox has, such as .LineCount , .Text , .CaretIndex , etc. I made a CaretIndex { get; set; } 为了解决此问题,我制作了自己的用户控件,它只是一个RichTextBox ,它具有TextBox大多数属性/方法,例如.LineCount.Text.CaretIndex等。我制作了CaretIndex { get; set; } CaretIndex { get; set; } CaretIndex { get; set; } property within my User-Control that looks like this: CaretIndex { get; set; }用户控件中的属性如下所示:

public int CaretIndex
        {
            get
            {
                TextPointer start = display.Document.ContentStart;
                TextPointer curPosition = display.CaretPosition;
                TextRange range = new TextRange(start, curPosition);
                return range.Text.Length;
            }
            set
            {
                display.CaretPosition = display.Document.ContentStart;
                for (int i = 0; i < value; i++)
                {
                    TextPointer move = display.CaretPosition.GetNextInsertionPosition(LogicalDirection.Forward);
                    if (move != null)
                        display.CaretPosition = move;
                }
            }
        }    

The get method seems to work fine, but set doesn't do what I envision it to accomplish. get方法似乎可以正常工作,但是set并没有实现我预期的目标。 My goal was to have the caret move logically forward a "value" amount of times - value being how many characters I want to move past - but the result is just abstract caret placement behavior. 我的目标是使插入符号在逻辑上向前移动“值”的次数-值是我要移动的字符数-但是结果只是抽象的插入符号放置行为。 The caret could either get placed a couple lines down, right below the original line, or all the way to the bottom of the RichTextBox . 插入符号可以放到原行下方几行,或者一直到RichTextBox的底部。

All I want is an easy way to move the caret left or right without undefined behavior. 我想要的是一种简单的方法,可以在没有不确定行为的情况下左右移动插入符号。 Am I approaching my CaretIndex property the wrong way? CaretIndex以错误的方式访问我的CaretIndex属性? Do I have a false perception of the CaretPosition property of a RichTextBox ? 我对RichTextBoxCaretPosition属性有CaretPosition吗? Any suggestions on what to do? 有什么建议吗?

I made a small wpf app to test your code - 我制作了一个小型的wpf应用来测试您的代码-

xaml - XAML-

<Grid.RowDefinitions>
    <RowDefinition Height="300"/>
    <RowDefinition Height="100"/>
    <RowDefinition Height="100"/>
</Grid.RowDefinitions>

<RichTextBox Grid.Row="0" Name="Rtb" />
<Button Grid.Row="1" Content="Get" Click="Button_Get" />

<Grid Grid.Row="2">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>

    <Button Grid.Column="0" Content="Set" Click="Button_Set" />
    <TextBox Grid.Column="1" Name="DesiredPositionBox" />
</Grid>

c# - C# -

    public MainWindow()
    {
        InitializeComponent();

        Rtb.AppendText("lineoftextlineoftextlineoftextlineoftext");
        Rtb.AppendText(Environment.NewLine);
        Rtb.AppendText("lineoftextlineoftextlineoftextlineoftext");
    }

    private void Button_Get(object sender, RoutedEventArgs e)
    {
        TextPointer start = Rtb.Document.ContentStart;
        TextPointer curPosition = Rtb.CaretPosition;
        TextRange range = new TextRange(start, curPosition);
        Debug.WriteLine("Caret position : " + range.Text.Length);

        Rtb.Focus();
    }

    private void Button_Set(object sender, RoutedEventArgs e)
    {
        int value = int.Parse(DesiredPositionBox.Text);

        Rtb.CaretPosition = Rtb.Document.ContentStart;
        for (int i = 0; i < value; i++)
        {
            TextPointer move = Rtb.CaretPosition.GetNextInsertionPosition(LogicalDirection.Forward);
            if (move != null)
                Rtb.CaretPosition = move;
        }

        Rtb.Focus();
    }

The line Rtb.CaretPosition = Rtb.Document.ContentStart; Rtb.CaretPosition = Rtb.Document.ContentStart; moves the caret to the start every time, so if you pass in '5' the caret will be moved to the 5th character from the start of the RichTextBox. 每次都将插入符号移到起始位置,因此,如果您输入'5',则插入符号将从RichTextBox的起始位置移至第5个字符。

Remove Rtb.CaretPosition = Rtb.Document.ContentStart; 删除Rtb.CaretPosition = Rtb.Document.ContentStart; and the caret will move x positions from where it was. 插入符号将从其原处移动x位置。

edit: To also answer how to place the caret at the end of the line, you can use Rtb.CaretPosition.GetTextRunLength(LogicalDirection.Forward) to get the number of characters, counting from the caret, before the first non text symbol ( which line break happens to be ). 编辑:还要回答如何将插入号放置在行的末尾,可以使用Rtb.CaretPosition.GetTextRunLength(LogicalDirection.Forward)获取从插入号开始计算的第一个非文本符号之前的字符数(换行符恰好是)。

So - 所以-

        int value = Rtb.CaretPosition.GetTextRunLength(LogicalDirection.Forward);
        TextPointer move = Rtb.CaretPosition.GetPositionAtOffset(value);
        Rtb.CaretPosition = move;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM