我正在创建一个扩展程序,围绕某些令牌绘制装饰,并提出下面的代码。只要代码在一行上,它就可以正常工作。只要我添加一个新行,就会在每次按键或滚动(LayoutChanged
事件)时在现有装饰品上重复绘制装饰品。
我可能做错了什么?另外,我在下面提出了自己的代码,因此可能存在根本性的错误。
private void CreateVisuals(ITextViewLine line)
{
var textViewLines = _wpfTextView.TextViewLines;
var text = line.Snapshot.GetText();
//var text = textViewLines.FormattedSpan.Snapshot.GetText();
var todoRegex = new Regex(@"\/\/\s*TODO\b");
var match = todoRegex.Match(text);
while (match.Success)
{
var matchStart = match.Index;
var span = new SnapshotSpan(_wpfTextView.TextSnapshot, Span.FromBounds(matchStart, matchStart + match.Length));
DrawAdornment(textViewLines, span);
match = match.NextMatch();
}
}
答案 0 :(得分:1)
因此,如果您在LayoutChanged
期间添加装饰品,则只需为正在布局的文本添加装饰品。您可以从TextViewLayoutChangedEventArgs.NewOrReformattedLines
获取正在中继的行列表。如果您通过VSSDK模板创建新的文本装饰,您将看到如何完成。
只要编辑器需要布局某些行,就会引发LayoutChanged
事件,但并不总是要排列所有行。例如,在滚动时,它只需要计算滚动到视图中的行的布局。如果插入/删除行,则不必向上或向下移动其他行。
(与您的问题无关,但仍然很重要:调用ITextSnapshot.GetText()的速度非常慢。如果您打开了一个多兆字节的文件,这将需要我们分配一个非常慢的字符串。实践中,GetText()应该只用于调试。如果您正在寻找TODO注释,并且您可以将其限制为Visual Studio 2015中的C#或VB代码,那么您真的应该查看Roslyn,它可以让您访问语法树信息。)