Выделение синтаксиса RichTextBox в режиме реального времени – отключение перерисовки

Я создаю функцию, которая принимает RichTextBox и имеет доступ к списку ключевых слов и «badwords». Мне нужно выделить любые ключевые слова и слова, которые я нахожу в RichTextBox во время ввода пользователем , что означает, что функция вызывается каждый раз, когда вы редактируете ключ.

Я написал эту функцию, но слова и курсор в поле мерцают слишком много для удобства.

Я обнаружил решение – отключить способность RichTextBox перерисовывать себя во время редактирования и форматирования его текста. Тем не менее, единственный способ, которым я это знаю, – переопределить функцию «WndProc» и перехватить (то, что я собирался собирать), это сообщение repaint следующим образом:

protected override void WndProc(ref System.Windows.Forms.Message m) { if (m.Msg == 0x00f) { if (paint) base.WndProc(ref m); else m.Result = IntPtr.Zero; } else base.WndProc(ref m); } 

Если логическая «краска» установлена ​​в false, перед тем, как я начну выделять ее и вернусь, когда закончу. Но, как я уже сказал, функция, которую я делаю, должна принимать RichTextBox; Я не могу использовать подclass.

Итак, есть ли способ отключить автоматическую перерисовку RichTextBox ‘извне?’

    Это надзор в classе RichTextBox. Другие элементы управления, такие как ListBox, поддерживают методы BeginUpdate и EndUpdate для подавления рисования. Эти методы генерируют сообщение WM_SETREDRAW. RTB фактически поддерживает это сообщение, но они забыли добавить методы.

    Просто добавьте их самостоятельно. Project + Add Class, вставьте код, показанный ниже. Скомпилируйте и опустите элемент управления сверху панели инструментов на свою форму.

     using System; using System.Windows.Forms; using System.Runtime.InteropServices; class MyRichTextBox : RichTextBox { public void BeginUpdate() { SendMessage(this.Handle, WM_SETREDRAW, (IntPtr)0, IntPtr.Zero); } public void EndUpdate() { SendMessage(this.Handle, WM_SETREDRAW, (IntPtr)1, IntPtr.Zero); this.Invalidate(); } [DllImport("user32.dll")] private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp); private const int WM_SETREDRAW = 0x0b; } 

    Или P / Invoke SendMessage непосредственно перед / после обновления текста.

    Я не набрал достаточного количества баллов, чтобы исправить рекомендацию Ганса. Поэтому я добавил этот ответ, чтобы упомянуть, что может потребоваться запросить перерисовку, вызвав InvalidateRect . Некоторые реализации Begin / End Update делают это автоматически после окончательной версии блокировки обновления. Аналогично в .Net, Control . Вызывается invalidate (), вызывающая функцию InvalidateRect .

    MSDN: Наконец, приложение может вызвать функцию InvalidateRect, чтобы вызвать перерисовку списка.

    См. WM_SETREDRAW

    Лучше всего сделать то, что вы пытаетесь сделать, – создать многопоточное приложение. Вы хотите создать один stream, который проверяет текст по вашему списку. Этот stream будет помещать любые экземпляры, которые он находит в очередь. Вы также захотите создать еще один stream, который делает фактическое выделение слов. Поскольку вам нужно будет использовать BeginInvoke () и Invoke () для обновления пользовательского интерфейса, вам нужно убедиться, что вы дросселируете скорость, с которой это вызвано. Я бы так больше 20 раз в секунду. Чтобы сделать это, вы должны использовать следующий код:

     DateTime lastInvoke=DateTime.Now; if ((DateTime.Now - lastInvoke).TotalMilliseconds >=42) { lastInvoke=DateTime.Now; ...Do your highlighting here... } 

    Этот stream проверяет вашу очередь на слова, которые нужно выделить или переосмыслить, и будет постоянно проверять очередь на любые новые обновления. Надеюсь, это имеет смысл!

    Давайте будем гением компьютера.