方式获得字光标位于在WPF RichTextBox控件(Way to obtain the word

2019-09-20 11:58发布



我想知道我怎么能得到这个词是当前光标是在WPF的RichTextBox。 我知道,RichTextBox中选中属性。 然而,这只是给了我是在RichTextBox中突出显示的文本。 相反,我想知道这个词光标在即使整个单词不突出。

任何提示赞赏。

非常感谢你。

Answer 1:

安装此功能任意RichTextBox的,现在被称为testRTB,并查看结果输出窗口:

private void testRTB_MouseUp(object sender, MouseButtonEventArgs e)
{
        TextPointer start = testRTB.CaretPosition;  // this is the variable we will advance to the left until a non-letter character is found
        TextPointer end = testRTB.CaretPosition;    // this is the variable we will advance to the right until a non-letter character is found

        String stringBeforeCaret = start.GetTextInRun(LogicalDirection.Backward);   // extract the text in the current run from the caret to the left
        String stringAfterCaret = start.GetTextInRun(LogicalDirection.Forward);     // extract the text in the current run from the caret to the left

        Int32 countToMoveLeft = 0;  // we record how many positions we move to the left until a non-letter character is found
        Int32 countToMoveRight = 0; // we record how many positions we move to the right until a non-letter character is found

        for (Int32 i = stringBeforeCaret.Length - 1; i >= 0; --i)
        {
            // if the character at the location CaretPosition-LeftOffset is a letter, we move more to the left
            if (Char.IsLetter(stringBeforeCaret[i]))
                ++countToMoveLeft;
            else break; // otherwise we have found the beginning of the word
        }


        for (Int32 i = 0; i < stringAfterCaret.Length; ++i)
        {
            // if the character at the location CaretPosition+RightOffset is a letter, we move more to the right
            if (Char.IsLetter(stringAfterCaret[i]))
                ++countToMoveRight;
            else break; // otherwise we have found the end of the word
        }



        start = start.GetPositionAtOffset(-countToMoveLeft);    // modify the start pointer by the offset we have calculated
        end = end.GetPositionAtOffset(countToMoveRight);        // modify the end pointer by the offset we have calculated


        // extract the text between those two pointers
        TextRange r = new TextRange(start, end);
        String text = r.Text;


        // check the result
        System.Diagnostics.Debug.WriteLine("[" + text + "]");
}

更改Char.IsLetter(...),以Char.IsLetterOrDigit(...)或任何其他适当根据您是否希望保留位数为好。

提示:提取到一个单独的组件中的扩展方法本访问它需要时。



Answer 2:

OK所以为了解决这个我蛮力迫使它。

我用curCaret.GetTextInRun(LogicalDirection.Backward)curCaret.GetTextInRun(LogicalDirection.Forward)

随着preCaretString.LastIndexOf(" ")postCaretString.IndexOf(" ")以及用于分隔词,并得到了其他子分隔。

最后,我添加字符串,字符串下半年上半年获得当前光标指示的话。

我打赌有这样的聪明的方式,但至少在这个问题解决了



Answer 3:

你可以通过鼠标的当前位置CaretPosition

不幸的是,没有简单的方法来获得字符插入位置的左/右。 我所知道的获得文本了一个RichTextBox的唯一方法是在这个答案 ,这是一个有点令人费解。 但它会完成什么是必要的。



Answer 4:

由于单词之间用空格分开,你可以到空间被发现通过围绕插入符的运行迭代。 该功能甚至应该工作的时候你RichTextBox甚至包含不同的字体和字体大小。

    public string GetWordByCaret(LogicalDirection direction)
    {
        // Get the CaretPosition
        TextPointer position = this.CaretPosition;
        TextPointerContext context = position.GetPointerContext(direction);

        string text = string.Empty;

        // Iterate through the RichTextBox based on the Start, Text and End of nearby inlines
        while (context != TextPointerContext.None)
        {
            // We are only interested in the text here
            //, so ignore everything that is not text
            if (context == TextPointerContext.Text)
            {
                string current = position.GetTextInRun(direction);

                // The strings appended based on whether they are before the caret or after it...
                // And well...I love switches :)
                switch (direction)
                {
                    case LogicalDirection.Backward:
                        {
                            int spaceIndex = current.LastIndexOf(' ');

                            // If space is found, we've reached the end
                            if (spaceIndex >= 0)
                            {
                                int length = current.Length - 1;

                                if (spaceIndex + 1 <= length)
                                {
                                    text = current.Substring(spaceIndex + 1, length - spaceIndex) + text;
                                }

                                return text;
                            }

                            else
                                text = current + text;
                        }
                        break;

                    default:
                        {
                            int spaceIndex = current.IndexOf(' ');

                            // If space is found, we've reached the end
                            if (spaceIndex >= 0)
                            {
                                int length = current.Length;

                                if (spaceIndex <= length)
                                {
                                    text += current.Substring(0, spaceIndex);
                                }

                                return text;
                            }

                            else
                                text += current;
                        }
                        break;
                }
            }

            // Move to the next position
            position = position.GetNextContextPosition(direction);

            // Get the next context
            if (position != null)
                context = position.GetPointerContext(direction);
            else
                context = TextPointerContext.None;
        }
        return text;
    }

现在,你可以让你插入记号是这样的话。

    string before = GetWordByCaret(LogicalDirection.Backward);
    string after = GetWordByCaret(LogicalDirection.Forward); 
    string word = before + after; // :)


Answer 5:

这是我使用LINQ和依赖项属性的替代解决方案:

public class SelectionRichTextBox : RichTextBox
{
    public SelectionRichTextBox()
    {
        // Use base class style
        SetResourceReference(StyleProperty, typeof(RichTextBox));
    }

    public static readonly DependencyProperty SelectedWordProperty =
        DependencyProperty.Register(
                "SelectedWord",
                typeof(string),
                typeof(SelectionRichTextBox),
                new PropertyMetadata("")
                );

    public string SelectedWord
    {
        get
        {
            return (string)GetValue(SelectedWordProperty);
        }
        set
        {
            SetValue(SelectedWordProperty, value);
        }
    }

    protected override void OnMouseUp(MouseButtonEventArgs e)
    {
        TextPointer cursorPosition = CaretPosition;

        string strBeforeCursor = cursorPosition.GetTextInRun(LogicalDirection.Backward);
        string strAfterCursor = cursorPosition.GetTextInRun(LogicalDirection.Forward);

        string wordBeforeCursor = strBeforeCursor.Split().Last();
        string wordAfterCursor = strAfterCursor.Split().First();

        string text = wordBeforeCursor + wordAfterCursor;

        SelectedWord = string.Join("", text
            .Where(c => char.IsLetter(c))
            .ToArray());

        base.OnMouseUp(e);
    }
}

在这之后,你可以在这样的结合使用:

    <custom:SelectionRichTextBox
            SelectedWord="{Binding SelectedWord, Mode=OneWayToSource}"/>


文章来源: Way to obtain the word cursor is on, in WPF RichTextBox Control