[英]AvalonEdit: Getting Visual Position for IBackgroundRenderer
在我的基於 AvalonEdit 的文檔編輯器中,我嘗試將標記線添加到文本視圖以指示文檔中的折疊,其方式類似於 Visual Studio 如何使用虛線連接代碼塊大括號的開頭和結尾。
如果文檔滾動到最頂部,我有一些可以產生正確結果的東西,但是如果向下滾動文檔,它不會正確更新。 具體來說,線條的繪制就好像文本視圖根本沒有滾動一樣,並且仍然位於文檔的頂部。 我懷疑這個問題與TextViewPosition
和GetVisualPosition
線有關,但我不明白如何通過滾動正確獲得調整后的視覺 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;
至於TextLocation
與TextViewPosition
:在某些情況下,map 到同一個TextLocation
的多個可能位置。 可能存在documentLength
為 0 的自定義VisualLineElement
。或者可能啟用了自動換行,並且在沒有空格字符的 position 處換行:然后第一個TextLine
的結尾和第二個TextLine
的開頭都引用到文檔中相同的 position。
TextViewPosition
帶有一些額外的信息,可以區分這些情況。 這對於插入符號最重要,因此單擊某處會將插入符號放置在單擊的 position 中; 不是另一個等效的 position。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.