C# WPF RichTextBox似乎添加了隐藏的填充

C# WPF RichTextBox似乎添加了隐藏的填充,c#,wpf,richtextbox,C#,Wpf,Richtextbox,这让我快发疯了。我正在写一个文本高亮器,它最终调用代码: TextPointer caret = textBox.CaretPosition; TextPointer contentStart = textBox.Document.ContentStart; TextPointer highlightStart = contentStart.GetPositionAtOffset(startPosition + 1, LogicalDirection.Forward); TextPointer

这让我快发疯了。我正在写一个文本高亮器,它最终调用代码:

TextPointer caret = textBox.CaretPosition;
TextPointer contentStart = textBox.Document.ContentStart;

TextPointer highlightStart = contentStart.GetPositionAtOffset(startPosition + 1, LogicalDirection.Forward);
TextPointer highlightEnd = contentStart.GetPositionAtOffset(endPosition + 2, LogicalDirection.Forward);

textBox.Selection.Select(highlightStart, highlightEnd);
textBox.Selection.ApplyPropertyValue(textElementProperty, value);
textBox.Selection.Select(caret, caret);

textBox.CaretPosition = caret;
实际的代码本身工作正常。。。。一旦问题是,一旦它高亮显示,就好像
RichTextBox
在高亮显示周围添加了隐藏的填充,这样当我在文本上运行
Regex
时,
Regex
返回正确的偏移量,但是它没有正确映射到
RichTextBox
中的正确字母。例如,如果我要突出显示“福克斯”一词,如:

那只敏捷的棕色狐狸跳过了那只懒狗

单词“fox”将正确突出显示,但如果我将“dog”更改为fox,它将显示为:

那只敏捷的棕色狐狸跳过了那头牛

但是,删除第一个“fox”将更正后一个版本,使其内容如下:

那只敏捷的棕色狗跳过了懒惰的狐狸

这几乎就像是
RichTextBox
添加了一些我在进行文本扫描时无法解释的填充

更新

我找到了解决这个问题的简单方法。但是,这似乎进一步证实了我的怀疑。如果我反向应用着色,这似乎可以修复它,如:

protected override void TextChanged(TextChangedEventArgs args) {
    var matches = regex.Matches(base.Text)
        .Cast<Match>()
        .Select(match => new {
            Start = match.Index,
            End = match.Index + match.Length
        }).Reverse();

    foreach (var match in matches) {
        Colorize(match.Start, match.End, TextElement.ForegroundProperty, Brushes.Blue);
    }

}
protected override void TextChanged(textchangedventargs args){
var matches=regex.matches(base.Text)
.Cast()
.选择(匹配=>新建){
Start=match.Index,
结束=匹配.索引+匹配.长度
}).Reverse();
foreach(匹配中的变量匹配){
着色(match.Start、match.End、TextElement.ForegroundProperty、Bruss.Blue);
}
}

看来我不该这么做。看起来很像是在添加填充或其他内容。

TextPointer API不仅计算字符,还计算符号,包括开始和结束标记等。请参阅MSDN上关于什么被计算为符号的备注部分


因此,当您添加一些格式时,它将抛出您稍后在文本中保存的符号偏移量。您必须从那里再次应用格式搜索,等等。或者反向操作也可以。

我考虑了一会儿,似乎最好的方法是一次获取所有位置标记,然后一次应用所有突出显示,以避开所有填充/移动。谢谢你的帮助。你可能想看看TextRange的资料。从内存中,如果设置myTextRange=TextRange(textPointer1,textPointer2),它将在编辑时保持其相对位置。你可以用myTextRange.ApplyPropertyValue(…)对它应用样式化是的,我就是这么做的。我预先计算了所有
TextPointer
/
TextRange
位置,然后应用更改。尽管
RichTextBox
的速度太慢了,我还是忍不住想手工重写所需的功能。