11

如果只给你一个特定文本的索引和长度(或 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;
        } 

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

rtb.Selection.ApplyPropertyValue(TextElement.BackgroundProperty, new SolidColorBrush(Colors.LightBlue));

突出显示功能仅在第一次尝试时有效,在第二次尝试后中断。有谁知道这是什么原因?

4

3 回答 3

6

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

当我尝试使用 RichTextBox 制作一些 Syntaxhighlighter 时,我遇到了类似的问题。我发现,当您使用 ApplyPropertyValue 玩arround时,您不能再简单地使用GetPositionAtOffset。我相信应用 propertyvalues 似乎改变了 TextTokens 在 Document 中的“内部位置”,因此“制动”了这个功能。

解决方法:

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

我不知道您是否应用了任何 PropertyValues 期望选择突出显示,因此您可能需要在其中进行更多思考。

这是我的代码在导致问题时的样子:

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

我像这样修复它:

    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));
        }
    }
于 2014-07-31T12:46:25.447 回答
-1

对RichTextBox.Selection属性使用Select()方法。

于 2012-08-22T02:48:44.313 回答
-1

Blockquote你可以得到空格之间的文字.....

私有字符串 RichWordOver(RichTextBox rch, int x, int y) {

        int pos = rch.GetCharIndexFromPosition(new Point(x, y));
        if (pos <= 0) return "";


        string txt = rch.Text;

        int start_pos;
        for (start_pos = pos; start_pos >= 0; start_pos--)
        {

            char ch = txt[start_pos];
            if (!char.IsLetterOrDigit(ch) && !(ch=='_')) break;
        }
        start_pos++;
        int end_pos;
        for (end_pos = pos; end_pos < txt.Length; end_pos++)
        {
            char ch = txt[end_pos];
            if (!char.IsLetterOrDigit(ch) && !(ch == '_')) break;
        }
        end_pos--;


        if (start_pos > end_pos) return "";
        return txt.Substring(start_pos, end_pos - start_pos + 1);
    }

private void rchText_MouseClick(object sender, MouseEventArgs e) { MessageBox.Show(RichWordOver(rchText, eX, eY)); }

于 2013-12-19T21:01:09.450 回答