我今天才发现这个,没有人回答!我只使用 AvalonEdit 一周左右,并使用以下命令添加了此功能:
应用 IndentGuideLinesRenderer 的代码:
// Create and add the custom background renderer
var indentGuideLinesRenderer = new IndentGuideLinesRenderer(editor);
editor.TextArea.TextView.BackgroundRenderers.Add(indentGuideLinesRenderer);
IndentGuideLinesRenderer 类:
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using ICSharpCode.AvalonEdit;
using ICSharpCode.AvalonEdit.Rendering;
using ICSharpCode.AvalonEdit.Utils;
public class IndentGuideLinesRenderer : IBackgroundRenderer
{
private ScrollViewer scrollViewer;
private TextEditor editor;
public IndentGuideLinesRenderer(TextEditor editor)
{
this.editor = editor;
scrollViewer = FindVisualChild<ScrollViewer>(editor);
if (scrollViewer != null)
{
// Override the scrolling behavior by handling the ScrollChanged event
scrollViewer.ScrollChanged += OnScrollChanged;
}
}
public KnownLayer Layer => KnownLayer.Background;
public void Draw(TextView textView, DrawingContext drawingContext)
{
Size pixelSize = PixelSnapHelpers.GetPixelSize(editor);
textView.EnsureVisualLines();
foreach (var visualLine in textView.VisualLines)
{
var line = editor.Document.GetLineByNumber(visualLine.FirstDocumentLine.LineNumber);
var text = editor.Document.GetText(line);
var indentation = 0;
foreach (var c in text)
{
// Check for spaces before text
if (c == ' ')
indentation++;
else
break;
// Draw the indent guide lines only for every second indentation
if (indentation >= 4 && (indentation - 4) % 4 == 0) // Adjust 4 to the desired indentation level
{
var startX = textView.GetVisualPosition(new TextViewPosition(line.LineNumber, indentation), VisualYPosition.TextTop).X - 5;
var startY = visualLine.GetTextLineVisualYPosition(visualLine.TextLines[0], VisualYPosition.LineTop) - editor.VerticalOffset;
var endY = visualLine.GetTextLineVisualYPosition(visualLine.TextLines[0], VisualYPosition.LineBottom) - editor.VerticalOffset;
// Create a dotted Pen
Pen dottedPen = new Pen(Brushes.LightGray, 1)
{
DashStyle = DashStyles.Dot, // or DashStyles.Dash for a dashed line
StartLineCap = PenLineCap.Square,
EndLineCap = PenLineCap.Square,
LineJoin = PenLineJoin.Miter
};
// Draw the indent guide line
if (IsDivisibleByMultipleOf(indentation, 8))
drawingContext.DrawLine(dottedPen, new System.Windows.Point(startX - pixelSize.Width / 2, startY + pixelSize.Height / 2), new System.Windows.Point(startX - pixelSize.Width / 2, endY + pixelSize.Height / 2));
else
drawingContext.DrawLine(dottedPen, new System.Windows.Point(startX, startY), new System.Windows.Point(startX, endY));
}
}
}
}
// Helper method to find a child of a specified type in the visual tree
private T FindVisualChild<T>(DependencyObject parent) where T : DependencyObject
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(parent, i);
if (child is T typedChild)
{
return typedChild;
}
else
{
T childOfChild = FindVisualChild<T>(child);
if (childOfChild != null)
{
return childOfChild;
}
}
}
return null;
}
// Function to check if a number is divisible by a multiple of another number
private bool IsDivisibleByMultipleOf(int number, int multiple)
{
return number % multiple == 0;
}
private void OnScrollChanged(object sender, ScrollChangedEventArgs e)
{
// Calls the InvalidateVisual method to refresh the vertical guide lines on scroll
editor.TextArea.TextView.InvalidateVisual();
}
}