FastColoredTextBox: как добавить большой текст — аналогично StringBuilder, но с использованием стилей — и без создания истории отмены.

FastColoredTextBox (FCTB) предоставляет методы, подобные StringBuilder, например, есть

public virtual void AppendText(строковый текст, стиль стиля)

и подобные методы. Однако каждое из этих действий рассматривается как ввод пользователя: каждое действие добавляется в историю отмены.

Я создаю свой текст программно, это поля данных и текст, а также все форматирование и стили, и он становится большим. В конце я выбрасываю эту историю отмены (или устанавливаю элемент управления только для чтения). Много памяти и времени вычислений тратится впустую. Прежде чем элемент управления можно будет использовать, пройдет несколько секунд.

Итак, есть ли способ составить мой текст перед передачей его в FCTB?

1 ответ

Создайте производный класс:

      public class TextBuilder : TextSource
{
    public Line CurrentLine { get; private set; }

    public TextBuilder(FastColoredTextBox t) : base(t)
    {
        AppendLine();
    }

    public void Append(string text, StyleIndex style = StyleIndex.None)
    {
        for (int i = 0; i < text.Length; i++)
        {
            char c = text[i];
            if (c == '\r' && i < text.Length - 1 && text[i + 1] == '\n') continue;
            if (c == '\r' || c == '\n') { AppendLine(); continue; }
            CurrentLine.Add(new Char(c, style));
        }
    }

    public void AppendLine(string text, StyleIndex style = StyleIndex.None)
    {
        Append(text, style);
        AppendLine();
    }

    public void AppendLine()
    {
        CurrentLine = CreateLine();
        lines.Add(CurrentLine);
    }

    public override void Initialized()
    {
        // Solution similar to CustomTextSourceSample.cs (not more than necessary)
        // (an alternative is OnTextChanged(0, lines.Count - 1) which invokes TextChanged but there may be side effects)

        if (CurrentTB.WordWrap)
        {
            OnRecalcWordWrap(new TextChangedEventArgs(0, lines.Count - 1));
        }

        CurrentTB.Invalidate();
    }
}

Добавьте этот виртуальный метод в класс:

      /// <summary>
/// Called when CurrentTB has initialized this text source.
/// </summary>
public virtual void Initialized()
{
}

В классе FCTB добавьте эту строку вInitTextSourceметод:

      while (LineInfos.Count < ts.Count)
    LineInfos.Add(new LineInfo(-1));

ts.Initialized(); // Add this line

ИзменитьCharконструктор для удобства:

      public Char(char c, StyleIndex s = StyleIndex.None)
{
    this.c = c;
    style = s;
}

Используйте следующим образом:

      var b = new TextBuilder(fctb);
b.Styles[0] = new MarkerStyle(Brushes.LightBlue);
b.Append("text", StyleIndex.Style0);
fctb.TextSource = b;

Если вы хотите сделать это без перекомпиляции FCTB, вы можете просто создатьTextBuilderкласс минус виртуальный метод и т. д. и вызватьb.OnTextChanged(0, b.Count - 1)после назначенияTextSource.

Другие вопросы по тегам