Avalonedit как программно изменить фон текста

Я хочу реализовать что-то, что программно изменяет фон текста при наличии строки документа. (Что-то, что очень похоже на выделение блока текста. проектирование). Я не хочу использовать выбор, так как он заставляет текстовое поле прокручиваться.

Я думаю, что мне нужно использовать DocumentColorizingTransformer, но я не уверен на 100%, как это сделать.

public class ColorizeAvalonEdit : ICSharpCode.AvalonEdit.Rendering.DocumentColorizingTransformer
    {
        protected override void ColorizeLine(ICSharpCode.AvalonEdit.Document.DocumentLine line)
        {
            int lineStartOffset = line.Offset;
            string text = CurrentContext.Document.GetText(line);
            int start = 0;
            int index;
            if (line.LineNumber == LogicSimViewCodeWPFCtrl.currentLine)
            {
                while ((index = text.IndexOf(text, start)) >= 0)
                {
                    base.ChangeLinePart(
                        lineStartOffset + index, // startOffset
                        lineStartOffset + index + text.Length, // endOffset
                        (VisualLineElement element) =>
                        {
                            element.TextRunProperties.SetBackgroundBrush(Brushes.Red);

                        });
                    start = index + 1; // search for next occurrence
                }
            }
        }
    }

currentLine — это часть, которая будет выделена.

Приведенный выше код работает правильно. Единственная проблема заключается в том, что если currentLine когда-либо изменяется, пока я просматриваю эту строку, она не выделяет обновленную строку, пока я не прокрутлю до другой части документа (скрывая обновленную строку) и не вернусь к обновленной строке.

Кроме того, как мне сделать, чтобы номера строк начинались с нуля?


person l46kok    schedule 10.08.2012    source источник


Ответы (3)


Поскольку это было их творение, я заглянул в исходники SharpDevelop и узнал, как они это сделали.

Они определили тип закладки (BreakpointBookmark) и добавили закладку в строку. Сама закладка устанавливает цвет линии в методе CreateMarker. Странно, что в SharpDevelop нет возможности настроить цвета точки останова.

Надеюсь, поможет.

    protected override ITextMarker CreateMarker(ITextMarkerService markerService)
    {
        IDocumentLine line = this.Document.GetLine(this.LineNumber);
        ITextMarker marker = markerService.Create(line.Offset, line.Length);
        marker.BackgroundColor = Color.FromRgb(180, 38, 38);
        marker.ForegroundColor = Colors.White;
        return marker;
    }
person Erdogan Kurtur    schedule 16.08.2012
comment
Оцените ответ. Однако, посмотрев на то, как SharpDevelop решает эту проблему, я думаю, что добавление большого количества классов, интерфейсов поверх внесения существенных изменений в код для реализации того, что кажется простой функцией, кажется неосуществимым. - person l46kok; 17.08.2012
comment
В глубине души SharpDevelop делает то же самое, что и вы. Он создает точки останова в виде маркеров закладок, которые являются TextSegments. В TextMarkerService.ColorizeLine он находит собственные маркеры (сегменты) и раскрашивает всю строку. Что вам нужно, чтобы создать всего один класс MyMarker:TextSegment и сохранить его в переменной типа. TextSegmentCollection‹TextMarker›. В ColorizeLine скопируйте из TextMarkerService.ColorizeLine, и все готово. - person Erdogan Kurtur; 17.08.2012
comment
Для номеров строк необходимо отредактировать LineNumberMargin.OnRender и собрать AvalonEdit. - person Erdogan Kurtur; 17.08.2012
comment
Но проблема не в том, что я не могу выделить текст. Проблема в том, что выделенная часть текста не аннулируется должным образом, несмотря на вызовы аннулирования, которые я делаю в приложении. Я все равно попробую это решение, чтобы увидеть, что я получу, но я, честно говоря, чувствую, что это излишество. - person l46kok; 20.08.2012

я нашел ответ

TxtEditCodeViewer.TextArea.TextView.Redraw();
person l46kok    schedule 21.08.2012

Разве это не дубликат этого вопрос?

Однако похоже, что вы должны вызывать InvalidateArrange() для редактора или InvalidateVisual() для каждого измененного визуального элемента.

person Louis Somers    schedule 18.08.2012
comment
Я звонил тем. Неудачно. Более конкретно: TxtEditCodeViewer.TextArea.TextView.InvalidateVisual(); TxtEditCodeViewer.TextArea.TextView.InvalidateArrange(); TxtEditCodeViewer.TextArea.TextView.InvalidateMeasure(); - person l46kok; 20.08.2012