簡體   English   中英

AvalonEdit:為 IBackgroundRenderer 獲取 Visual Position

[英]AvalonEdit: Getting Visual Position for IBackgroundRenderer

在我的基於 AvalonEdit 的文檔編輯器中,我嘗試將標記線添加到文本視圖以指示文檔中的折疊,其方式類似於 Visual Studio 如何使用虛線連接代碼塊大括號的開頭和結尾。

如果文檔滾動到最頂部,我有一些可以產生正確結果的東西,但是如果向下滾動文檔,它不會正確更新。 具體來說,線條的繪制就好像文本視圖根本沒有滾動一樣,並且仍然位於文檔的頂部。 我懷疑這個問題與TextViewPositionGetVisualPosition線有關,但我不明白如何通過滾動正確獲得調整后的視覺 position。

(需要明確的是,我已經檢查過了,並且在適當的時候調用了Draw方法來更新背景,只是在滾動時沒有考慮到滾動)

到目前為止,我在實現IBackgroundRenderer的 class 上擁有以下內容:

public void Draw(TextView textView, DrawingContext drawingContext) {
    if (textView == null) { throw new ArgumentNullException("textView"); }
    if (drawingContext == null) { throw new ArgumentNullException("drawingContext"); }
    if (!textView.VisualLinesValid) { return; }
    ReadOnlyCollection<VisualLine> visualLines = textView.VisualLines;
    if (visualLines.Count == 0) { return; }

    foreach (FoldingSection fold in foldingManager.AllFoldings.Where(f => !f.IsFolded)) {

        DocumentLine startLine = textView.Document.GetLineByOffset(fold.StartOffset);
        ISegment whitespace = TextUtilities.GetLeadingWhitespace(textView.Document, startLine);
        if(whitespace.Length == 0) { continue; }
        DocumentLine endLine = textView.Document.GetLineByOffset(fold.EndOffset);

        TextLocation foldStart = textView.Document.GetLocation(whitespace.EndOffset);
        TextLocation foldEnd = textView.Document.GetLocation(textView.Document.GetOffset(endLine.LineNumber, foldStart.Column));

        // I am unsure exactly what TextViewPosition is meant to represent, in contrast to TextLocation
        TextViewPosition startViewPos = new TextViewPosition(foldStart);
        TextViewPosition endViewPos = new TextViewPosition(foldEnd);

        // These lines are definitely not returning what I expect
        Point foldStartPos = textView.GetVisualPosition(startViewPos, VisualYPosition.LineBottom);
        Point foldEndPos = textView.GetVisualPosition(endViewPos, VisualYPosition.LineBottom);

        Brush brush = new SolidColorBrush(LineColor);
        brush.Freeze();
        Pen dashPen = new Pen(brush, 0.5) { DashStyle = new DashStyle(new double[] { 2, 2 }, 0) };
        dashPen.Freeze();
        // New point created to avoid issues with nested folds causing slanted lines
        drawingContext.DrawLine(dashPen, foldStartPos, new Point(foldStartPos.X, foldEndPos.Y));
    }
}

文檔的折疊基於空格(非常類似於 Python 樣式的縮進),因此使用前導空格來查找列。

簡而言之,如何從文檔的行號和列中獲得正確調整的視覺 position?

GetVisualPosition記錄為:

返回: WPF 中的 position 相對於文檔左上角的設備無關像素。

要將其用於繪畫,您需要從中減去滾動 position:

Point foldStartPos = textView.GetVisualPosition(startViewPos, VisualYPosition.LineBottom);
Point foldEndPos = textView.GetVisualPosition(endViewPos, VisualYPosition.LineBottom);
foldStartPos -= textView.ScrollOffset;
foldEndPos -= textView.ScrollOffset;

至於TextLocationTextViewPosition :在某些情況下,map 到同一個TextLocation的多個可能位置。 可能存在documentLength為 0 的自定義VisualLineElement 。或者可能啟用了自動換行,並且在沒有空格字符的 position 處換行:然后第一個TextLine的結尾和第二個TextLine的開頭都引用到文檔中相同的 position。

TextViewPosition帶有一些額外的信息,可以區分這些情況。 這對於插入符號最重要,因此單擊某處會將插入符號放置在單擊的 position 中; 不是另一個等效的 position。

暫無
暫無

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

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