Более быстрый способ раскрасить все вхождения в RichTextBox в C # - PullRequest
3 голосов
/ 03 октября 2010

У меня есть RichTextBox, и существует около 1000 вхождений указанной строки поиска.

Я использую следующую функцию, чтобы закрасить все вхождения:

public void ColorAll(string s)
{
    rtbxContent.BeginUpdate();

    int start = 0, current = 0;
    RichTextBoxFinds options = RichTextBoxFinds.MatchCase;
    start = rtbxContent.Find(s, start, options);
    while (start >= 0)
    {
        rtbxContent.SelectionStart  = start;
        rtbxContent.SelectionLength = s.Length;
        rtbxContent.SelectionColor     = Color.Red;
        rtbxContent.SelectionBackColor = Color.Yellow;

        current = start + s.Length;
        if (current < rtbxContent.TextLength)
            start = rtbxContent.Find(s, current, options);
        else
            break;
    }

    rtbxContent.EndUpdate();
}

Но я обнаружил, что это очень медленно.

Однако, если я раскрасю все вхождения другого слова, у которого меньше текста, в одном и том же тексте, я обнаружу, что это очень быстро.

Так что я думаю, что медлительность от (эти две строки могут включать обновление пользовательского интерфейса):

    rtbxContent.SelectionColor     = Color.Red;
    rtbxContent.SelectionBackColor = Color.Yellow;

Есть ли более быстрый способ выполнения той же работы, например, я делаю раскраску в памяти, а затем отображаю результат за один раз?

Я проясняю себя?

Спасибо.

Ответы [ 4 ]

1 голос
/ 01 мая 2015

Существует более быстрый способ.

Используйте регулярные выражения, чтобы найти совпадения, затем выделите в поле richtextbox

    if (this.tBoxFind.Text.Length > 0)
    {
        try
        {
               this.richTBox.SuspendLayout();
               this.Cursor = Cursors.WaitCursor;

           string s = this.richTBox.Text;
           System.Text.RegularExpressions.MatchCollection mColl = System.Text.RegularExpressions.Regex.Matches(s, this.tBoxFind.Text);

           foreach (System.Text.RegularExpressions.Match g in mColl)
           {
                  this.richTBox.SelectionColor = Color.White;
                  this.richTBox.SelectionBackColor = Color.Blue;

                  this.richTBox.Select(g.Index, g.Length);
           }
   }
   finally
   {
         this.richTBox.ResumeLayout();
         this.Cursor = Cursors.Default;
   }
}
1 голос
/ 03 октября 2010

Количество времени, которое требуется прямо пропорционально количеству происшествий.

Вероятно, это Находка, которая использует больше всего времени. Вы можете заменить эту строку:

    start = rtbxContent.Find(s, start + s.Length, options); 

с этим:

    start = rtbxContent.Find(s, current, options);

Поскольку вы вычислили ток равным старту + s.Length

Вы также можете хранить переменную s.Length, поэтому вам не нужно каждый раз подсчитывать все символы в строке. То же самое касается rtbxContent.TextLength.

0 голосов
/ 22 апреля 2015

Вы на правильном пути, в чем виновата медленная реализация Winforms RichTextBox.Вы также хорошо использовали методы BeginUpdate и EndUpdate (я полагаю, вы взяли их из здесь ?).Но, увы, этого недостаточно.

Несколько решений:

1: Попробуйте записать RTF непосредственно в текстовое поле.Это довольно запутанный, сложный формат, но, к счастью, я создал ответ здесь , который поможет.

2: Этот высоко оцененный внешний проект также выглядит достойным внимания:http://www.codeproject.com/Articles/161871/Fast-Colored-TextBox-for-syntax-highlighting

0 голосов
/ 03 октября 2010

Поиск строки является линейным.Если вы находите метод Find медленным, возможно, вы можете использовать сторонний инструмент для поиска вас.Все, что вам нужно, это индекс шаблона в строке.

Может быть , это поможет вам Вы должны рассчитать разницу и использовать более быструю.

...