AvalonEdit: выделять текущую строку, даже если она не сфокусирована

Я использую AvalonEdit, и я хочу, чтобы пользователь всегда мог видеть, на какой строке находится курсор, даже когда редактор нет фокуса. С этой целью я нашел и адаптировал код, который использует BackgroundRenderer для выделения фона текущей строки.

К сожалению, если я изменяю CaretOffset, когда редактор не сфокусирован, мой фоновый прямоугольник остается на линии, которая была текущей, когда редактор потерял фокус. Он не синхронизируется с новой текущей строкой, пока редактор снова не получит фокус.

Я выяснил , почему это происходит (но не как это исправить). Согласно комментариям к документу для IBackgroundRenderer, «Фоновый рендерер будет рисовать только в том случае, если его связанный известный слой выберет их рисовать. Например, фоновые рендереры в слое курсора будут невидимы, когда курсор скрыт». Мой фоновый рендерер живет на KnownLayer.Caret, так что да, я понимаю, почему он не обновляется, когда редактор не сфокусирован - это потому, что курсор также скрыт. (Учитывая это, я действительно удивлен, что мой прямоугольник остается видимым. )

Я попытался явно вызвать textEditor.TextArea.TextView.InvalidateLayer (KnownLayer.Caret) сразу после того, как установил CaretOffset, но это не дало результата - я предполагаю, что вызов был проигнорирован, потому что курсор был скрыт.

Как лучше всего принудительно обновить выделение текущей строки, даже если редактор не имеет фокуса?


Вот код для моего класса. Я, конечно, готов выбросить это и использовать другой подход, если есть лучший способ сделать это.

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));
15
задан Goswin 2 September 2014 в 16:34
поделиться