C# AvaloneEdit:获取IBackgroundRenderer的可视位置

C# AvaloneEdit:获取IBackgroundRenderer的可视位置,c#,wpf,avalonedit,C#,Wpf,Avalonedit,在基于AvalonEdit的文档编辑器中,我尝试向文本视图添加标记线,以指示文档中的折叠,类似于Visual Studio将代码块的开始和结束大括号与虚线连接的方式 如果将文档滚动到最顶端,我会得到正确的结果,但如果将文档向下滚动,则不会正确更新。具体地说,这些线条的绘制就好像文本视图根本没有滚动过一样,并且仍然位于文档的顶部。我怀疑问题与TextViewPosition和GetVisualPosition行有关,但我不知道如何通过滚动正确获得调整后的视觉位置 (为了清楚起见,我已经检查了,并且

在基于AvalonEdit的文档编辑器中,我尝试向文本视图添加标记线,以指示文档中的折叠,类似于Visual Studio将代码块的开始和结束大括号与虚线连接的方式

如果将文档滚动到最顶端,我会得到正确的结果,但如果将文档向下滚动,则不会正确更新。具体地说,这些线条的绘制就好像文本视图根本没有滚动过一样,并且仍然位于文档的顶部。我怀疑问题与
TextViewPosition
GetVisualPosition
行有关,但我不知道如何通过滚动正确获得调整后的视觉位置

(为了清楚起见,我已经检查了,并且在适当的时候调用了
Draw
方法来更新背景,只是滚动没有被考虑在内)

到目前为止,我在一个实现了
IBackgroundRenderer
的类上拥有以下内容:

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));
    }
}
public void Draw(TextView TextView,DrawingContext DrawingContext){
如果(textView==null){抛出新的ArgumentNullException(“textView”);}
如果(drawingContext==null){抛出新的ArgumentNullException(“drawingContext”);}
如果(!textView.VisualLinesValid){return;}
ReadOnlyCollection visualLines=textView.visualLines;
如果(visualLines.Count==0){return;}
foreach(FoldingSection折叠在foldingManager.AllFoldings.Where中(f=>!f.isfolding)){
DocumentLine startLine=textView.Document.GetLineByOffset(fold.StartOffset);
ISegment whitespace=TextUtilities.GetLeadingWhitespace(textView.Document,startLine);
如果(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));
//与TextLocation相比,我不确定TextViewPosition到底代表什么
TextViewPosition startViewPos=新的TextViewPosition(foldStart);
TextViewPosition endViewPos=新的TextViewPosition(折叠);
//这些线肯定没有返回我所期望的
Point foldStartPos=textView.GetVisualPosition(startViewPos,VisualPosition.LineBottom);
Point foldEndPos=textView.GetVisualPosition(endViewPos,VisualPosition.LineBottom);
笔刷=新的SolidColorBrush(LineColor);
刷子。冻结();
Pen dashPen=新画笔(画笔,0.5){DashStyle=新的DashStyle(新双精度[]{2,2},0)};
dashPen.Freeze();
//创建新点以避免嵌套折叠导致斜线的问题
drawingContext.DrawLine(dashPen、foldStartPos、new Point(foldStartPos.X、foldEndPos.Y));
}
}
文档的折叠基于空格(非常类似于Python样式的缩进),因此使用前导空格查找列


简而言之,如何从文档行号和列中获得适当调整的可视位置?

GetVisualPosition
记录如下:

返回:WPF设备独立像素相对于文档左上角的位置

要将其用于绘制,您需要从中减去滚动位置:

PointFoldStartPos=textView.GetVisualPosition(startViewPos,VisualYPosition.LineBottom);
Point foldEndPos=textView.GetVisualPosition(endViewPos,VisualPosition.LineBottom);
foldStartPos-=textView.ScrollOffset;
foldEndPos-=textView.ScrollOffset;
至于
TextLocation
TextViewPosition
:在某些情况下,有多个可能的位置映射到同一
TextLocation
。 可能有自定义的
VisualLineElement
s的
documentLength
为0。 或者,可能启用了换行,并在没有空格字符的位置换行:然后第一个
文本行的结尾和第二个
文本行的开头都指向文档中的相同位置

TextViewPosition
带有一些额外的信息,可以区分这些情况。这对于插入符号非常重要,因此单击某个位置会将插入符号放置在单击的位置;不是另一个同等的职位