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
.