簡體   English   中英

AvalonEdit:即使沒有聚焦,也要突出顯示當前行

[英]AvalonEdit: highlight current line even when not focused

我正在使用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)));
        }
    }
}

然后在我的UserControl的構造函數中,我將渲染器添加到編輯器:

textEditor.TextArea.TextView.BackgroundRenderers.Add(
    new HighlightCurrentLineBackgroundRenderer(textEditor));

這是我如何完成這項工作。

首先,我更改了HighlightCurrentLineBackgroundRenderer的Layer屬性以返回KnownLayer.Background。 即使編輯器沒有焦點,背景圖層也是可見的,因此可以解決原始問題。

然而,它引入了一個新問題:背景層只在某些條件下被重繪,而“插入移動”不是這些條件之一 - 所以現在突出顯示根本不會移動! (嗯,確實如此 - 例如,滾動時,或選擇文本時。但這不是理想的行為。)但這很容易解決; 我只需要在插入符號移動時手動使背景層無效:

textEditor.TextArea.Caret.PositionChanged += (sender, e) =>
    textEditor.TextArea.TextView.InvalidateLayer(KnownLayer.Background);

這就是它的全部 - 即使編輯器沒有專注,現在突出顯示也會更新。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM