AvalonEdit WPF TextEditor (SharpDevelop):如何突出显示特定范围的文本?

发布于 2024-10-17 18:17:42 字数 785 浏览 9 评论 0原文

令人难以置信的 AvalonEdit WPF TextEditor 控件似乎缺少一个重要的功能,或者至少我无法弄清楚。 给定偏移量和长度,使用 HighlightColor 突出显示 TextDocument 中的该部分。很简单,对吧?

显然不是。我有 RTFM,“语法突出显示”的文档让我更加困惑。 其他人在 SharpDevelop 论坛中提出了同样的问题,我恐怕我无法理解格伦沃尔德先生的回答。

这是我的尝试,使用 DocumentHighlighter 类(当然它不起作用):

    textEditor1.Text = "1234567890";

    HighlightingColor c = new HighlightingColor() { FontWeight = FontWeights.ExtraBold };

    DocumentHighlighter dh = new DocumentHighlighter(textEditor1.Document, new HighlightingRuleSet());
    HighlightedLine hl = dh.HighlightLine(1);

    hl.Sections.Add(new HighlightedSection() { Color = c, Offset = 1, Length = 3 });

谢谢您的帮助!

The incredibly awesome AvalonEdit WPF TextEditor control seems to lack an important feature, or at least i can't figure it out. Given an offset and a length, highlight that portion in the TextDocument with a HighlightColor. Simple, right?

Apprentely not. I've RTFM, and the documentation on "Syntax Highlighting" confused me even more. Someone else asked the same question in the SharpDevelop forums, and i'm afraid i can't make sense of Herr Grunwald's answer.

Here's my attempt, using the DocumentHighlighter class (of course it doesn't work):

    textEditor1.Text = "1234567890";

    HighlightingColor c = new HighlightingColor() { FontWeight = FontWeights.ExtraBold };

    DocumentHighlighter dh = new DocumentHighlighter(textEditor1.Document, new HighlightingRuleSet());
    HighlightedLine hl = dh.HighlightLine(1);

    hl.Sections.Add(new HighlightedSection() { Color = c, Offset = 1, Length = 3 });

Thank you for helping!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

抱猫软卧 2024-10-24 18:17:42

您是否在这篇文章中看到了这一点 - 这似乎正是您所要求的:

public class ColorizeAvalonEdit : DocumentColorizingTransformer
{
protected override void ColorizeLine(DocumentLine line)
{
    int lineStartOffset = line.Offset;
    string text = CurrentContext.Document.GetText(line);
    int start = 0;
    int index;
    while ((index = text.IndexOf("AvalonEdit", start)) >= 0) {
        base.ChangeLinePart(
            lineStartOffset + index, // startOffset
            lineStartOffset + index + 10, // endOffset
            (VisualLineElement element) => {
                // This lambda gets called once for every VisualLineElement
                // between the specified offsets.
                Typeface tf = element.TextRunProperties.Typeface;
                // Replace the typeface with a modified version of
                // the same typeface
                element.TextRunProperties.SetTypeface(new Typeface(
                    tf.FontFamily,
                    FontStyles.Italic,
                    FontWeights.Bold,
                    tf.Stretch
                ));
            });
        start = index + 1; // search for next occurrence
}   }   }

它用粗体突出显示单词 AvalonEdit。

Did you see this in this article - it seems to be exactly what are you asking for:

public class ColorizeAvalonEdit : DocumentColorizingTransformer
{
protected override void ColorizeLine(DocumentLine line)
{
    int lineStartOffset = line.Offset;
    string text = CurrentContext.Document.GetText(line);
    int start = 0;
    int index;
    while ((index = text.IndexOf("AvalonEdit", start)) >= 0) {
        base.ChangeLinePart(
            lineStartOffset + index, // startOffset
            lineStartOffset + index + 10, // endOffset
            (VisualLineElement element) => {
                // This lambda gets called once for every VisualLineElement
                // between the specified offsets.
                Typeface tf = element.TextRunProperties.Typeface;
                // Replace the typeface with a modified version of
                // the same typeface
                element.TextRunProperties.SetTypeface(new Typeface(
                    tf.FontFamily,
                    FontStyles.Italic,
                    FontWeights.Bold,
                    tf.Stretch
                ));
            });
        start = index + 1; // search for next occurrence
}   }   }

It highlights word AvalonEdit with bold.

窗影残 2024-10-24 18:17:42

一些背景信息:
AvalonEdit 是一个代码编辑器,而不是富文本编辑器。不存在“突出显示文档的一部分”这样的事情 - 文档仅存储纯文本。

突出显示是按需计算的,仅针对当前视图中的行。如果您想要自定义突出显示,则需要向突出显示计算添加一个步骤 - 这就是 mzabsky 发布的示例中的 ColorizeAvalonEdit 类所做的事情。

Some background info:
AvalonEdit is a code editor, not a rich text editor. There is no such thing as "highlight a portion of the document" - the document only stores plain text.

Highlighting is computed on-demand, only for the lines currently in view. If you want custom highlighting, you need to add a step to the highlighting computation - this is what the ColorizeAvalonEdit class in the example posted by mzabsky is doing.

优雅的叶子 2024-10-24 18:17:42

您需要创建一个自定义 ColorizingTransformer 来执行此操作。上面的例子实际上是突出显示一个特定的单词。不过,您可以稍微更改它以着色或突出显示一部分。

我在我的 Console+ 项目中使用了 Avalon TextEditor(目前处于非常原始的阶段)

public class OffsetColorizer : DocumentColorizingTransformer
{
    public int StartOffset { get; set; }
    public int EndOffset { get; set; }

    protected override void ColorizeLine(DocumentLine line)
    {
        if (line.Length == 0)
            return;

        if (line.Offset < StartOffset || line.Offset > EndOffset)
            return;

        int start = line.Offset > StartOffset ? line.Offset : StartOffset;
        int end = EndOffset > line.EndOffset ? line.EndOffset : EndOffset;

        ChangeLinePart(start, end, element => element.TextRunProperties.SetForegroundBrush(Brushes.Red));
    }
}

,你可以通过将着色器添加到 LineTransformers 集合来将其添加到编辑器。

tbxConsole.TextArea.TextView.LineTransformers.Add(_offsetColorizer);

You need to create a custom ColorizingTransformer to do that. The above example is actually highlighting a specific word. Still, you can change it a little bit to to colorize or highlight a portion.

I used Avalon TextEditor for my Console+ project (which is in a very primitive stage at the moment)

public class OffsetColorizer : DocumentColorizingTransformer
{
    public int StartOffset { get; set; }
    public int EndOffset { get; set; }

    protected override void ColorizeLine(DocumentLine line)
    {
        if (line.Length == 0)
            return;

        if (line.Offset < StartOffset || line.Offset > EndOffset)
            return;

        int start = line.Offset > StartOffset ? line.Offset : StartOffset;
        int end = EndOffset > line.EndOffset ? line.EndOffset : EndOffset;

        ChangeLinePart(start, end, element => element.TextRunProperties.SetForegroundBrush(Brushes.Red));
    }
}

And you can add the colorizer to the editor by adding it to LineTransformers collection.

tbxConsole.TextArea.TextView.LineTransformers.Add(_offsetColorizer);
み青杉依旧 2024-10-24 18:17:42

我知道这是一个很老的问题,但我想我会分享我的解决方案。我不确定这个解决方案是否已在 AvalonEdit 中实现,因为这个问题最初已得到回答,但我发现 OffsetColorizer 类实际上并没有选择该行:它只是更改了该行的背景颜色。

我的解决方案如下:

textEditor.SelectionStart = offset;

textEditor.SelectionLength = length;

但是,这可以进一步扩展,如下所示:

public void SelectText(int offset, int length)
{
    //Get the line number based off the offset.
    var line = textEditor.Document.GetLineByOffset(offset);
    var lineNumber = line.LineNumber;

    //Select the text.
    textEditor.SelectionStart = offset;
    textEditor.SelectionLength = length;

    //Scroll the textEditor to the selected line.
    var visualTop = textEditor.TextArea.TextView.GetVisualTopByDocumentLine(lineNumber);
    textEditor.ScrollToVerticalOffset(visualTop); 
}

我发现这个解决方案效果更好的是,它不仅仅是对线条进行着色,而是实际上选择了它:这意味着可以使用 Ctrl+C 复制它。

我希望这对未来的人们有所帮助。

I know this is a pretty old question, but I thought I would share my solution. I am not sure if this solution has been implemented into AvalonEdit, since this question was originally answered, but I find the OffsetColorizer class doesn't actually select the line: it just changes the line's background colour.

My solution is as follows:

textEditor.SelectionStart = offset;

textEditor.SelectionLength = length;

However, this can be extended further like so:

public void SelectText(int offset, int length)
{
    //Get the line number based off the offset.
    var line = textEditor.Document.GetLineByOffset(offset);
    var lineNumber = line.LineNumber;

    //Select the text.
    textEditor.SelectionStart = offset;
    textEditor.SelectionLength = length;

    //Scroll the textEditor to the selected line.
    var visualTop = textEditor.TextArea.TextView.GetVisualTopByDocumentLine(lineNumber);
    textEditor.ScrollToVerticalOffset(visualTop); 
}

I find that this solution works better is that rather than just colouring the line, it actually selects it: meaning it can be copied using Ctrl+C.

I Hope this helps people in the future.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文