В моем редакторе документов на основе 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));
}
}
Свертывание документа основано на пробелах (очень похоже на отступы в стиле Python), поэтому для поиска столбца используется начальный пробел.
Короче говоря, как получить правильно настроенное визуальное положение по номеру строки и столбцу документа?