You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在WPF中为RichTextBox或AvalonEdit实现RuleLine(暗线)

实现编辑器每行RuleLine(暗线)的方案

一、使用AvalonEdit实现

AvalonEdit自带灵活的自定义渲染接口,很适合做这类编辑器样式定制:

  1. 自定义行背景渲染器
    创建实现IBackgroundRenderer接口的类,专门绘制每行暗线:
using ICSharpCode.AvalonEdit.Rendering;
using System.Windows.Media;

public class RuleLineRenderer : IBackgroundRenderer
{
    public KnownLayer Layer => KnownLayer.Background;

    public void Draw(TextView textView, DrawingContext drawingContext)
    {
        var pen = new Pen(Brushes.LightGray, 0.5);
        pen.Freeze();

        foreach (var visualLine in textView.VisualLines)
        {
            var lineTop = visualLine.TextLine.GetLineBounds(0).Top;
            var lineY = textView.TextLinesToPixels(lineTop);
            var startPoint = new Point(textView.ActualWidth, lineY);
            var endPoint = new Point(0, lineY);
            
            drawingContext.DrawLine(pen, startPoint, endPoint);
        }
    }
}
  1. 绑定到AvalonEdit控件
    在窗口初始化或控件加载时,把渲染器添加到AvalonEdit的TextView中:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
    avalonEdit.TextArea.TextView.BackgroundRenderers.Add(new RuleLineRenderer());
}

这样每行底部会自动出现淡灰色暗线,且能跟随编辑器滚动、行高变化实时更新。

二、使用RichTextBox实现

RichTextBox需要通过装饰器(Adorner)实现跨行暗线绘制:

  1. 创建自定义Adorner类
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;

public class RuleLineAdorner : Adorner
{
    private readonly RichTextBox _richTextBox;
    private readonly Pen _pen;

    public RuleLineAdorner(RichTextBox richTextBox) : base(richTextBox)
    {
        _richTextBox = richTextBox;
        _pen = new Pen(Brushes.LightGray, 0.5);
        _pen.Freeze();
        _richTextBox.ScrollChanged += OnScrollChanged;
    }

    private void OnScrollChanged(object sender, ScrollChangedEventArgs e)
    {
        InvalidateVisual();
    }

    protected override void OnRender(DrawingContext drawingContext)
    {
        base.OnRender(drawingContext);
        var document = _richTextBox.Document;
        if (document == null) return;

        var startPos = document.ContentStart;
        while (startPos != null)
        {
            if (startPos.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.Text)
            {
                var rect = startPos.GetCharacterRect(LogicalDirection.Forward);
                // 避开第一行顶部空白,只绘制行底部的线
                if (rect.Y > _richTextBox.Padding.Top)
                {
                    var lineY = rect.Bottom;
                    var startPoint = new Point(_richTextBox.Padding.Left, lineY);
                    var endPoint = new Point(_richTextBox.ActualWidth - _richTextBox.Padding.Right, lineY);
                    drawingContext.DrawLine(_pen, startPoint, endPoint);
                }
            }
            startPos = startPos.GetNextContextPosition(LogicalDirection.Forward);
        }
    }
}
  1. 添加装饰器到RichTextBox
    在控件加载时,将装饰器添加到RichTextBox的AdornerLayer:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
    var adornerLayer = AdornerLayer.GetAdornerLayer(richTextBox);
    adornerLayer.Add(new RuleLineAdorner(richTextBox));
}

这个实现会监听滚动事件,确保滚动时暗线正确刷新,同时适配RichTextBox的内边距设置。

内容的提问来源于stack exchange,提问作者sodiseng

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 03:43:18