突出显示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); }
TOP
正确突出显示但不是file
或end
但突出显示我or
。
有什么建议?
你必须想象RichTextBox在幕后做了什么来理解行为。 我不完全确切,但我想到以下内容:第1-2行设置为RichTextBox
的内容,带有Run
的Paragraph
。
然后使用ApplyPropertyValue
进行第一次迭代, ApplyPropertyValue
的内容会发生变化! 它现在包含一个带有Span
(内部Run
)和运行的Paragraph
。
然后你必须考虑正则表达式匹配和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); }
*免责声明:我现在还没有尝试过,因为我不在发展环境附近。 我甚至不知道这是否编译,但我希望如此。