【问题标题】:Highlight text in RichTextBox突出显示 RichTextBox 中的文本
【发布时间】:2011-08-06 20:06:32
【问题描述】:

我正在尝试使用 RichTextBox,我的第一感觉是:“使用起来有什么复杂的!”... 太棒了...

所以我试图突出显示我的 RichTextBox 中包含的文本。

我目前有以下代码:

TextRange range = new TextRange(MyTextInput.Document.ContentStart, MyTextInput.Document.ContentEnd);
range.Text = @"TOP a multiline text or file END";
Regex reg = new Regex("(top|file|end)", RegexOptions.Compiled | RegexOptions.IgnoreCase);

foreach (Match match in reg.Matches(range.Text))
{
    TextPointer start = range.Start.GetPositionAtOffset(match.Index, LogicalDirection.Forward);
    TextPointer end = range.Start.GetPositionAtOffset(match.Index + match.Length, LogicalDirection.Backward);
    // text contains the exact match I want
    string text = range.Text.Substring(match.Index, match.Length);
    // here the highlighted text isn't the text I searched...
    TextRange textrange = new TextRange(start, end);
    textrange.ApplyPropertyValue(TextElement.ForegroundProperty, new SolidColorBrush(Colors.Blue));
    textrange.ApplyPropertyValue(TextElement.FontWeightProperty, FontWeights.Bold);
}

TOP 正确突出显示,但 fileend 未正确突出显示,但突出显示我 or

有什么建议吗?

【问题讨论】:

    标签: c# wpf richtextbox syntax-highlighting


    【解决方案1】:

    您必须想象 RichTextBox 在幕后做了什么才能理解其行为。我不太清楚,但我想如下:第 1-2 行设置为 RichTextBox 的内容 ParagraphRun

    然后在使用ApplyPropertyValue 的第一次迭代中,RichTextBox 的内容发生了变化!它现在包含一个 Paragraph 和一个 Span(内部有一个 Run)和一个 Run。

    然后您必须考虑正则表达式匹配和GetPositionAtOffset 之间的差异。正则表达式匹配返回字符串中字符位置的索引。

    GetPositionAtOffset 使用“以符号为单位的偏移量,用于计算并返回位置” 符号所在的位置:

    • TextElement 元素的开始或结束标记。
    • 包含在 InlineUIContainer 或 BlockUIContainer 中的 UIElement 元素。请注意,这样的 UIElement 始终只计为一个符号; UIElement 包含的任何其他内容或元素都不算作符号。
    • 文本 Run 元素中的 16 位 Unicode 字符。

    所以你可能想做的是这样的:

    TextRange range = new TextRange(MyTextInput.Document.ContentStart, MyTextInput.Document.ContentEnd);
    range.Text = @"TOP a multiline text or file END";
    Regex reg = new Regex("(top|file|end)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
    
    var start = MyTextInput.Document.ContentStart;
    while (start != null && start.CompareTo(MyTextInput.Document.ContentEnd) < 0)
    {
        if (start.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.Text)
        {
            var match=reg.Match(start.GetTextInRun(LogicalDirection.Forward));
    
            var textrange = new TextRange(start.GetPositionAtOffset(match.Index, LogicalDirection.Forward), start.GetPositionAtOffset(match.Index + match.Length, LogicalDirection.Backward));
            textrange.ApplyPropertyValue(TextElement.ForegroundProperty, new SolidColorBrush(Colors.Blue));
            textrange.ApplyPropertyValue(TextElement.FontWeightProperty, FontWeights.Bold);
            start= textrange.End; // I'm not sure if this is correct or skips ahead too far, try it out!!!
        }
        start = start.GetNextContextPosition(LogicalDirection.Forward);
    }
    

    *免责声明:我还没有尝试过,因为现在我离开发环境还很远。我什至不知道这是否编译,但我希望如此。

    【讨论】:

    • 它编译和工作,恭喜! (感谢您的解释,但是,对于我来说,RichTextBox 目前是一个大黑盒子......)
    • 很棒的答案,但这是一个很好的例子,var 的使用让我感到困惑。因为我不熟悉这些属性并且不知道例如ContentStart 是索引(可能是)还是字符或其他什么。
    • 对不起,这种方式对于长文本来说太慢了。
    • 我不敢相信这么简单的功能有这么多代码(例如与 html 相比)。代码效果很好。 Tyvm
    猜你喜欢
    • 2020-12-24
    • 2018-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-12
    • 1970-01-01
    • 2011-08-26
    相关资源
    最近更新 更多