突出显示RichTextBox中的文本

Arn*_* F. 13 c# wpf syntax-highlighting richtextbox

我正在尝试使用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);
}
Run Code Online (Sandbox Code Playgroud)

TOP正确突出但不file还是end而是突出了我or.

有什么建议?

Mar*_*ter 18

你必须想象一下RichTextBox在幕后做些什么才能理解行为.我并不确切地知道,但我想象中的以下内容:第1-2行设定为内容RichTextBox一个ParagraphRun.

然后在第一次迭代时,ApplyPropertyValueRichTextBox的内容会发生变化!现在,它包含一个ParagraphSpan(带Run内)和运行.

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

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);
}
Run Code Online (Sandbox Code Playgroud)

*免责声明:我现在还没有尝试这个,我离开发环境不远.我甚至不知道这是否编译,但我希望如此.

  • 抱歉,但这种方式对于长文本来说太慢了. (4认同)
  • 它编译并运行,恭喜!(感谢您的解释,但是,对我来说,RichTextBox 目前是一个大黑匣子......) (2认同)