不幸的是,如果我在编辑器没有焦点时更改 CaretOffset,则我的背景矩形会保持不变,停留在编辑器失去焦点时的行上。它直到编辑器重新获得焦点才会同步更新到新的当前行。
我找出了为什么会发生这种情况(只是不知道如何修复它)。根据 IBackgroundRenderer 的文档注释,“背景渲染器仅在其关联的已知图层选择绘制时才会绘制它们。例如,当光标隐藏时,光标图层中的背景渲染器将不可见。”我的背景渲染器位于 KnownLayer.Caret 上,所以我明白为什么它在编辑器没有焦点时不更新——因为光标也被隐藏了。(考虑到这一点,我实际上很惊讶我的矩形仍然可见。)
我尝试在设置 CaretOffset 后立即显式调用 textEditor.TextArea.TextView.InvalidateLayer(KnownLayer.Caret),但没有效果——我猜测调用被忽略了,因为光标被隐藏了。
在编辑器没有焦点时,强制更新当前行高亮的最佳方法是什么?
这是我的类代码。如果有更好的方法,请告诉我,我很愿意放弃目前的方式。
public class HighlightCurrentLineBackgroundRenderer : IBackgroundRenderer
{
private TextEditor _editor;
public HighlightCurrentLineBackgroundRenderer(TextEditor editor)
{
_editor = editor;
}
public KnownLayer Layer
{
get { return KnownLayer.Caret; }
}
public void Draw(TextView textView, DrawingContext drawingContext)
{
if (_editor.Document == null)
return;
textView.EnsureVisualLines();
var currentLine = _editor.Document.GetLineByOffset(_editor.CaretOffset);
foreach (var rect in BackgroundGeometryBuilder.GetRectsForSegment(textView, currentLine))
{
drawingContext.DrawRectangle(
new SolidColorBrush(Color.FromArgb(0x40, 0, 0, 0xFF)), null,
new Rect(rect.Location, new Size(textView.ActualWidth - 32, rect.Height)));
}
}
}
然后在我的UserControl的构造函数中,我将渲染器添加到编辑器中:
textEditor.TextArea.TextView.BackgroundRenderers.Add(
new HighlightCurrentLineBackgroundRenderer(textEditor));