我试图使用一个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
的内容,Paragraph
与Run
。
然后与ApplyPropertyValue
的第一次迭代RichTextBox的内容得到改变!它现在包含一个Paragraph
和一个Span
(里面有一个Run
)和一个Run.
然后你必须考虑Regex匹配和GetPositionAtOffset
之间的差异。Regex匹配返回字符串中字符位置的索引。
GetPositionAtOffset使用"以符号表示的偏移量,用于计算并返回位置",其中符号为:
- TextElement元素的开始或结束标签。
- 一个包含在InlineUIContainer或BlockUIContainer中的元素。注意,这样的一个元素总是被精确地计算为一个符号;任何附加的内容或元素都不被视为符号。
- text 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);
}
*免责声明:我还没有尝试过这个,因为现在我没有一个开发环境。我甚至不知道这是否可以编译,但我希望可以。