Эффективное выделение поля форматированного текста с большим текстом в форме окна

У меня есть огромные текстовые файлы, которые я обрабатываю построчно и добавляю результаты в StringBuilder, поэтому я не храню основную форму с загрузкой в ​​нее отдельных строк текста.

После завершения обработки я выгружаю результат в richtext textbox. Я хочу выделить часть текста на основе имеющихся у меня ключевых слов. В итоге я использую строку. Найдите во всем тексте каждое слово, чтобы выделить его. Я попытался создать поток, чтобы выделить текст с помощью лямбда-выражения richbox.BeginInvoke. поток работает нормально, но берет на себя дескриптор поля форматированного текста и работает очень медленно.

Как просмотреть richtext box строку за строкой и выделить некоторые слова с понятной производительностью, учитывая 50–100 МБ текста ?.

Этот вопрос был перемещен от суперпользователя, потому что его программирование актуально. Предлагаются следующие решения: http://www.dotnetcurry.com/ShowArticle.aspx?ID=146 и http://www.codeproject.com/Articles/4031/Background-Highlighting-with-the-RichTextBox-the-S, но они по-прежнему неэффективны для больших текстов.

foreach (string x in LArgs)
{
    int len =0;
    int index = 0;
    int lastIndex=0;
    output.Invoke(() => { len=output.Text.Length; });
    output.Invoke(() => { lastIndex=output.Text.LastIndexOf(x); });
    while (index < lastIndex)
    {
        output.Invoke(() => { output.Find(x, index, len, RichTextBoxFinds.None); });
        output.Invoke(() => { this.output.SelectionBackColor = Color.Yellow; });
        output.Invoke(() => { index = this.output.Text.IndexOf(x, index) + 1; });
    }
}

Я добавил библиотеку и использовал этот код:

scintilla1.Text = output.Text;

StringBuilder conf = new StringBuilder();
conf.AppendLine("<?xml version=\"1.0\" encoding=\"utf-8\" ?>");
conf.AppendLine(@"<ScintillaNET>");
conf.AppendLine("<Language Name=\"log\">");
conf.AppendLine("<lexer LexerName=\"log\">");
conf.AppendLine("<Keywords List=\"0\">");

foreach (string x in LArgs)
{
    conf.Append(x + " ");
}
//var
conf.AppendLine("</Keywords>");
conf.AppendLine(@"</lexer >");
conf.AppendLine(@"<Styles>");

conf.AppendLine(@"</Language>");
conf.AppendLine(@"</ScintillaNET>");

File.WriteAllText(AppDomain.CurrentDomain.BaseDirectory+@"ScintillaNET.xml", conf.ToString());
scintilla1.Lexing.LexerLanguageMap["log"] = "cpp";
scintilla1.ConfigurationManager.CustomLocation = AppDomain.CurrentDomain.BaseDirectory + @"ScintillaNET.xml";
scintilla1.ConfigurationManager.Language = "log";
scintilla1.ConfigurationManager.Configure();

Текст загружен, но он не выделяет текст или текст, который я добавлю позже.


person CodeEmpower    schedule 26.01.2013    source источник
comment
Возможен ли вариант ВПП? В таком случае я делаю это с помощью FlowDocument и создаю его в BackGroundWorker. Раньше я делал это в Forms RichTextBox, и это было больно.   -  person paparazzo    schedule 27.01.2013
comment
решение должно быть обратно совместимо с некоторой библиотекой: /   -  person CodeEmpower    schedule 28.01.2013


Ответы (1)


Можете ли вы использовать внешние библиотеки?

Тогда как насчет Scintilla.Net

Это действительно хороший и быстрый элемент управления подсветкой на основе Scintilla (SciTE, Notepad ++).

person codeteq    schedule 28.01.2013
comment
У меня возникли проблемы с файлом конфигурации XML, а именно со словом Lexer. Кроме того, этот фреймворк поддерживает до 9 пользовательских слов, что в моем случае является серьезным ограничением. - person CodeEmpower; 29.01.2013