AvalonEdit:即使没有聚焦,也要突出显示当前行

Joe*_*ite 15 c# avalonedit

我正在使用AvalonEdit,我希望用户始终能够看到插入符号所在的行,即使编辑器没有焦点.为此,我发现并修改了一些使用BackgroundRenderer突出显示当前行背景的代码.

不幸的是,如果我在编辑器未聚焦时更改了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)));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在我的UserControl的构造函数中,我将渲染器添加到编辑器:

textEditor.TextArea.TextView.BackgroundRenderers.Add(
    new HighlightCurrentLineBackgroundRenderer(textEditor));
Run Code Online (Sandbox Code Playgroud)

Joe*_*ite 15

这是我如何完成这项工作.

首先,我更改了HighlightCurrentLineBackgroundRenderer的Layer属性以返回KnownLayer.Background.即使编辑器没有焦点,背景图层也是可见的,因此可以解决原始问题.

然而,它引入了一个新问题:背景层只在某些条件下被重绘,而"插入移动"不是这些条件之一 - 所以现在突出显示根本不会移动!(嗯,确实如此 - 例如,滚动时,或选择文本时.但这不是理想的行为.)但这很容易解决; 我只需要在插入符号移动时手动使背景层无效:

textEditor.TextArea.Caret.PositionChanged += (sender, e) =>
    textEditor.TextArea.TextView.InvalidateLayer(KnownLayer.Background);
Run Code Online (Sandbox Code Playgroud)

这就是它的全部 - 即使编辑器没有专注,现在突出显示也会更新.