【问题标题】:Whole line highlighting in AvalonEditAvalonEdit 中的整行高亮显示
【发布时间】:2014-03-14 20:35:20
【问题描述】:

我正在使用 AvalonEdit 为补丁文件创建一个视图,我想让它在整行中突出显示差异,而不仅仅是文本背景 - 类似于 GitHub for Windows 今天所做的:

我是 AvalonEdit 的新手,所以我不确定最好的方法。以下是我目前发现的:

  • 重写 VisualLineElementGenerator 以创建一个附加的 TextSpan,它是控件的长度。这似乎很棘手。

  • 创建一个新控件以在后台添加到TextView.Layers,并手动添加到绿色/红色的 OnRender - 这似乎更有希望,但还不清楚我需要挂钩什么事件才能检测何时重新渲染。

  • 覆盖 TextView - 这似乎有点过头了。

编辑:这是一个简单的语法荧光笔会发生什么,这是我想要的:

【问题讨论】:

标签: c# wpf avalonedit


【解决方案1】:

正如 Daniel 提到的,我通过 Wiki 页面发现了背景渲染器,并且效果很好。这就是我最终做的事情——它可能会变得更有效率,但现在已经足够了:

public class DiffLineBackgroundRenderer : IBackgroundRenderer
{
    static Pen pen;

    static SolidColorBrush removedBackground;
    static SolidColorBrush addedBackground;
    static SolidColorBrush headerBackground;

    FileDiffView host;

    static DiffLineBackgroundRenderer()
    {
        removedBackground = new SolidColorBrush(Color.FromRgb(0xff, 0xdd, 0xdd)); removedBackground.Freeze();
        addedBackground = new SolidColorBrush(Color.FromRgb(0xdd, 0xff, 0xdd)); addedBackground.Freeze();
        headerBackground = new SolidColorBrush(Color.FromRgb(0xf8, 0xf8, 0xff)); headerBackground.Freeze();

        var blackBrush = new SolidColorBrush(Color.FromRgb(0, 0, 0)); blackBrush.Freeze();
        pen = new Pen(blackBrush, 0.0);
    }

    public DiffLineBackgroundRenderer(FileDiffView host)
    {
        this.host = host;
    }

    public KnownLayer Layer 
    {
        get { return KnownLayer.Background; }
    }

    public void Draw(TextView textView, DrawingContext drawingContext)
    {
        foreach (var v in textView.VisualLines) 
        {
            var rc = BackgroundGeometryBuilder.GetRectsFromVisualSegment(textView, v, 0, 1000).First();
            // NB: This lookup to fetch the doc line number isn't great, we could
            // probably do it once then just increment.
            var linenum = v.FirstDocumentLine.LineNumber - 1;
            if (linenum >= host.ViewModel.Lines.Count) continue;

            var diffLine = host.ViewModel.Lines[linenum];

            if (diffLine.Style == DiffLineStyle.Context) continue;

            var brush = default(Brush);
            switch (diffLine.Style)
            {
            case DiffLineStyle.Header:
                brush = headerBackground;
                break;
            case DiffLineStyle.Added:
                brush = addedBackground;
                break;
            case DiffLineStyle.Deleted:
                brush = removedBackground;
                break;
            }

            drawingContext.DrawRectangle(brush, pen, 
                new Rect(0, rc.Top, textView.ActualWidth, rc.Height));
        }
    }
}

【讨论】:

  • 您的FileDiffView 模型的基础是什么?我有两个 AvalonEditor 并排,我真的很难逐行比较他们的文本以区分它们。
  • @Jack,搜索最长公共子序列算法。见xmailserver.org/diff2.pdf
【解决方案2】:

手动创建一个新控件添加到背景的TextView.Layers和绿色/红色的OnRender

您不必创建新层来在后台渲染某些内容:您可以将IBackgroundRenderer 的实现添加到textView.BackgroundRenderers 以在现有层的背景中渲染某些内容。

不清楚我需要挂钩什么事件才能检测何时重新渲染

那就是:textView.VisualLinesChanged。但是,如果您使用 IBackgroundRenderer,则不需要这样做,因为 AvalonEdit 已经重新渲染了现有图层。

【讨论】:

    猜你喜欢
    • 2017-07-05
    • 1970-01-01
    • 2011-08-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-19
    • 2013-12-04
    • 2011-12-13
    • 2011-07-06
    相关资源
    最近更新 更多