【发布时间】:2019-02-21 15:14:16
【问题描述】:
我对FlowDocument有一个误解,请帮我看清楚。 我正在开发一个源代码编辑器,用户可以在其中添加一些特殊变量,然后程序会查找这些变量。对于这个编辑器,我使用的是 RichTextBox(RTB)。我想为这些变量使用颜色。当用户向文本添加新变量时,添加颜色不是问题。但是当用户首先打开一个已经有一些变量的源代码时,我必须深入研究整个文本并对变量进行着色。
下面的代码: 首先,我使用正则表达式搜索所有变量及其位置。(变量看起来像:)然后循环槽并一一更改颜色,但是当我制作 TextRange 时,GetPositionAtOffset 会返回错误的值.我知道这是因为 GetPositionAtOffset 也计算了特殊格式字符。 问题是,我该如何解决这个问题?
private void ColorizeAllVariable(TextRange TR_Input)
{
Regex regex = new Regex(@"(<\*.[^<\*>]*\*>)");
MatchCollection matches = regex.Matches(TR_Input.Text);
NoRTBChangeEvent = true;
for (int i = 0; i < matches.Count; i++)
{
TextRange TR_Temp = new TextRange(TR_Input.Start.GetPositionAtOffset(matches[i].Index), TR_Input.Start.GetPositionAtOffset(matches[i].Index + matches[i].Length));
TR_Temp.ApplyPropertyValue(TextElement.ForegroundProperty, Brushes.DodgerBlue);
}
NoRTBChangeEvent = false;
}
更新 1:
按照user8478480 解决方案,我更改了我的代码。
private void ColorizeAllVariable(RichTextBox richTextBox)
{
IEnumerable<TextRange> WordRanges = GetAllWordRanges(richTextBox.Document, @"(<\*.[^<\*>]*\*>)");
foreach (TextRange WordRange in WordRanges)
{
WordRange.ApplyPropertyValue(TextElement.ForegroundProperty, Brushes.DodgerBlue);
}
}
private static IEnumerable<TextRange> GetAllWordRanges(FlowDocument document, string pattern)
{
TextPointer pointer = document.ContentStart;
while (pointer != null)
{
if (pointer.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.Text)
{
string textRun = pointer.GetTextInRun(LogicalDirection.Forward);
MatchCollection matches = Regex.Matches(textRun, pattern);
foreach (Match match in matches)
{
int startIndex = match.Index;
int length = match.Length;
TextPointer start = pointer.GetPositionAtOffset(startIndex);
TextPointer end = start.GetPositionAtOffset(length);
yield return new TextRange(start, end);
}
}
pointer = pointer.GetNextContextPosition(LogicalDirection.Forward);
}
}
它直接寻找看起来像的单词。它找到了所有单词,但格式字符仍然存在问题。
This is the result. The second word in the line has wrong coloring position
This is how the line looks like, when it search for the word
我看到了问题,当我添加颜色属性时,它会移动数据,但我的匹配包含着色之前的位置。
看起来很简单,如果我在一行中有多个匹配项,我总是将位置移动一个常数值。但是格式化字符看起来并不总是相同的长度。正如您在第二次尝试中看到的那样,第一个可变颜色是正确的。比第二个有 5 个字符移位,第三个变量也有 5 个字符移位,第四个变量有 9 个字符移位,第五个变量有 13 个字符移位,第六个......(我不知道这里发生了什么) ,最后第七个变量的颜色位置也很好。
【问题讨论】:
标签: wpf richtextbox