如何在给定索引和长度的情况下选择RichTextBox文本

l46*_*kok 11 .net c# wpf richtextbox

如果只给出要选择的某个文本的索引和长度(或EndIndex),那么如何在WPF版本的RichTextBox中执行此操作?

这在Textbox中是非常可行的,因为你可以调用Textbox.Select(startIndex,Length)但我在RTB中看不到任何等价物.

编辑:我找到了做出选择的答案

internal string Select(RichTextBox rtb, int index, int length)
        {
            TextRange textRange = new TextRange(rtb.Document.ContentStart, rtb.Document.ContentEnd);

            if (textRange.Text.Length >= (index + length))
            {
                TextPointer start = textRange.Start.GetPositionAtOffset(index, LogicalDirection.Forward);
                TextPointer end = textRange.Start.GetPositionAtOffset(index + length, LogicalDirection.Backward);
                rtb.Selection.Select(start, end);
            }
            return rtb.Selection.Text;
        } 
Run Code Online (Sandbox Code Playgroud)

但是,当我在选择完成后尝试突出显示该行时:

rtb.Selection.ApplyPropertyValue(TextElement.BackgroundProperty, new SolidColorBrush(Colors.LightBlue));
Run Code Online (Sandbox Code Playgroud)

突出显示功能仅在第一次尝试时起作用,在第二次尝试后中断.有谁知道这个的原因?

CSh*_*pie 6

好的,这个问题很旧,但是我终于找到了答案,所以我把它放在了这里。

当我尝试使用RichTextBox创建一些Syntaxhighlighter时,我遇到了类似的问题。我发现,当您与ApplyPropertyValue一起玩时,您不能再简单地使用GetPositionAtOffset。我认为,应用属性值似乎会更改文档内TextToken的“内部位置”,从而“激活”此功能。

解决方法:

每次您需要使用GetPositionAtOffset时,首先在文档的完整TextRange上调用ClearAllProperties,然后使用ApplyPropertyValue重新应用所有属性,但这一次是从右到左。(右表示最高偏移量)

我不知道您是否已应用任何PropertyValues期望Selection高亮显示,因此您可能需要在其中进行更多思考。

这是我的代码引起问题时的样子:

    private void _highlightTokens(FlowDocument document)
    {
        TextRange fullRange = new TextRange(document.ContentStart, document.ContentEnd);
        foreach (Token token in _tokenizer.GetTokens(fullRange.Text))
        {
            TextPointer start = fullRange.Start.GetPositionAtOffset(token.Position);
            TextPointer end = start.GetPositionAtOffset(token.Length);

            TextRange range = new TextRange(start, end);
            range.ApplyPropertyValue(TextElement.ForegroundProperty, _getTokenColor(token));
        }
    }
Run Code Online (Sandbox Code Playgroud)

我像这样修复它:

    private void _highlightTokens(FlowDocument document)
    {
        TextRange fullRange = new TextRange(document.ContentStart, document.ContentEnd);
        fullRange.ClearAllProperties(); // NOTICE: first remove allProperties.
        foreach (Token token in _tokenizer.GetTokens(fullRange.Text).Reverse()) // NOTICE: Reverse() to make the "right to left" work
        {
            TextPointer start = fullRange.Start.GetPositionAtOffset(token.Position);
            TextPointer end = start.GetPositionAtOffset(token.Length);

            TextRange range = new TextRange(start, end);
            range.ApplyPropertyValue(TextElement.ForegroundProperty, _getTokenColor(token));
        }
    }
Run Code Online (Sandbox Code Playgroud)