Я ищу идеи по эффективному способу реализации окна журнала для приложения форм Windows. В прошлом я реализовал несколько, используя TextBox и RichTextBox, но я до сих пор не полностью удовлетворен функциональностью.
Этот журнал предназначен для предоставления пользователю новейшей истории различных событий, в основном используемых в приложениях сбора данных, где может быть любопытно, как завершена конкретная транзакция. В этом случае журнал не обязательно должен быть постоянным и не сохраняться в файле.
Во-первых, некоторые предлагаемые требования:
- Эффективный и быстрый; если сотни строк записываются в журнал в быстрой последовательности, он должен потреблять минимальные ресурсы и время.
- Уметь предлагать переменную прокрутку до 2000 строк или около того. Ничего более не нужно.
- Предпочтительны подсветка и цвет. Эффекты шрифта не требуются.
- Автоматически обрезать линии по достижении предела прокрутки.
- Автоматическая прокрутка по мере добавления новых данных.
- Бонус, но не требуется: Пауза автопрокрутки во время ручного взаимодействия, например, если пользователь просматривает историю.
Что я использовал до сих пор, чтобы писать и обрезать журнал:
Я использую следующий код (который я вызываю из других потоков):
// rtbLog is a RichTextBox
// _MaxLines is an int
public void AppendLog(string s, Color c, bool bNewLine)
{
if (rtbLog.InvokeRequired)
{
object[] args = { s, c, bNewLine };
rtbLog.Invoke(new AppendLogDel(AppendLog), args);
return;
}
try
{
rtbLog.SelectionColor = c;
rtbLog.AppendText(s);
if (bNewLine) rtbLog.AppendText(Environment.NewLine);
TrimLog();
rtbLog.SelectionStart = rtbLog.TextLength;
rtbLog.ScrollToCaret();
rtbLog.Update();
}
catch (Exception exc)
{
// exception handling
}
}
private void TrimLog()
{
try
{
// Extra lines as buffer to save time
if (rtbLog.Lines.Length < _MaxLines + 10)
{
return;
}
else
{
string[] sTemp = rtxtLog.Lines;
string[] sNew= new string[_MaxLines];
int iLineOffset = sTemp.Length - _MaxLines;
for (int n = 0; n < _MaxLines; n++)
{
sNew[n] = sTemp[iLineOffset];
iLineOffset++;
}
rtbLog.Lines = sNew;
}
}
catch (Exception exc)
{
// exception handling
}
}
Проблема с этим подходом заключается в том, что всякий раз, когда вызывается TrimLog, я теряю форматирование цвета. С обычным TextBox это работает просто отлично (с небольшим изменением, конечно).
Поиски решения этого никогда не были действительно удовлетворительными. Некоторые предлагают обрезать избыток по числу символов вместо количества строк в RichTextBox. Я также видел ListBoxes, но не успешно его пробовал.