繁体   English   中英

如何突出显示 RichTextBox 中的特定文本?

[英]How to highlight specific text in a RichTextBox?

RichTextBox控件中,我试图通过正则表达式匹配以红色突出显示特定文本。

样本:

此文本语句工作正常,并以红色突出显示“院长”:

从客户端中选择前 10 个 * 其中 MailName='Deans'

此文本语句也可以正常工作,并以红色阴影突出显示代码:

从客户端中选择前 10 个 * 其中 MailName='De a ns'

但是这个说法失败了:

从客户端中选择前 10 个 * 其中 MailName='Deans '

它失败是因为单引号之间有空格,它在使开始 TextRange 的行上引发异常

TextRange result = new TextRange(start, start.GetPositionAtOffset(word.Length)); 

异常说:

无效的参数位置 2。

请建议我一个解决方案。 我在哪里犯了错误?

这是代码片段:

string StringFromRichTextBox(RichTextBox rtb)
{
    TextRange textRange = new TextRange(rtb.Document.ContentStart,      
                rtb.Document.ContentEnd);

    return textRange.Text;
}

private void TextChangedEventHandler(object sender, TextChangedEventArgs e)
{
    TextRange documentRange = new TextRange(txtQueries.Document.ContentStart, txtQueries.Document.ContentEnd);
        documentRange.ClearAllProperties();

    MatchCollection match = Regex.Matches(StringFromRichTextBox(txtQueries), @"'([^']*)'");
    for (int z = 0; z < match.Count; z++)
    {
        CheckKeyword(documentRange, match[z].ToString().Trim());
    }
}

private void CheckKeyword(TextRange textRange, string word)
{
    //txtQueries.TextChanged -= this.TextChangedEventHandler;
    if (textRange.Text.Contains(word))
    {
        int offset = textRange.Text.IndexOf(word);
        if (offset < 0)
        {
            return;
        }// Not found
        else
        {
            // Try to select the text as a contiguous range
            for (TextPointer start = textRange.Start.GetPositionAtOffset(offset); start != textRange.End; start = start.GetPositionAtOffset(1))
            {
                try
                {
                    TextRange result = new TextRange(start, start.GetPositionAtOffset(word.Length));
                    if (result != null && result.Text == word)  
                    {
                        result.ApplyPropertyValue(TextElement.ForegroundProperty, new SolidColorBrush(Colors.Red));
                        break;
                    }
                }
                catch(Exception ex)
                {
                    throw new Exception(ex.Message);
                }
            }
        }
    }
    //txtQueries.TextChanged += this.TextChangedEventHandler;
}

错误信息:

值不能为空。 参数名称:在 System.Windows.Documents.TextRange..ctor(TextPointer position1, TextPointer position2) 处的 position2

解决方案 :: 向偏移长度添加了 4,以解决在 Richtextbox 中出现空格的特殊不可见字符。

    var length = word.Length;
                // Try to select the text as a contiguous range
                for (TextPointer start = textRange.Start.GetPositionAtOffset(offset); start != textRange.End; start = start.GetPositionAtOffset(1))
                {
                    try
                    {

                        TextRange result = new TextRange(start, start.GetPositionAtOffset(word.Contains(" ") ? word.Length + 4: word.Length)); //Added 4 to the offset length to account for special invisible characters coming up with space in richtext box
                        if (result.Text.Trim() == word.Trim())  
                        {
                            result.ApplyPropertyValue(TextElement.ForegroundProperty, new SolidColorBrush(Colors.Red));
                            break;
                        }

                    }
                    catch (Exception ex)
                    {
                        throw new Exception(ex.Message);
                    }

我在处理这个问题时也遇到了很多麻烦! 在使用GetPositionAtOffset进行了大量 wtf 之后,我想出了这个方法来在RichTextBox搜索时获得准确的TextPointer

public static TextRange FindStringRangeFromPosition(TextPointer position, string str) {
     //what makes this work is checking the PointerContext so you avoid the markup characters   
     while (position != null) {
            if (position.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.Text) {
                string textRun = position.GetTextInRun(LogicalDirection.Forward);

                // Find the starting index of any substring that matches "str".
                int indexInRun = textRun.IndexOf(str);
                if (indexInRun >= 0) {
                //since we KNOW we're in a text section we can find the endPointer by the str.Length now
                    return new TextRange(position.GetPositionAtOffset(indexInRun), position.GetPositionAtOffset(indexInRun + str.Length));
                }
            }
            position = position.GetNextContextPosition(LogicalDirection.Forward);
        }

        // position will be null if "str" is not found.
        return null;
    }

暂无
暂无

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

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