Как предотвратить обновление отображения RichTextBox?

У меня есть RichTextBox, где мне нужно часто обновлять свойство Text, но когда я это делаю, RichTextBox раздражающе «мигает», поскольку он обновляется на протяжении всего вызова метода.

Я надеялся найти простой способ временно подавить обновление экрана, пока мой метод не будет выполнен, но единственное, что я нашел в Интернете, - это переопределить метод WndProc. Я использовал этот подход, но с некоторыми трудностями и побочными эффектами, а также усложняет отладку. Просто кажется, что должен быть лучший способ сделать это. Может ли кто-нибудь указать мне лучшее решение?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
10
0
9 327
6

Ответы 6

Попробуйте это:

myRichTextBox.SuspendLayout();
DoStuff();
myRichTextBox.ResumeLayout();

вам также может потребоваться добавить myRichTextBox.Enabled = false; а более поздний Enabled = true;

Geoff 10.10.2008 21:57

SuspendLayout () здесь не помогает.

DK. 11.10.2008 00:30

Не могли бы вы просто сохранить текст в строке, произвести манипуляции со строкой и в конце метода сохранить его обратно в свойство Text?

Найдено здесь: http://bytes.com/forum/thread276845.html

I ended up sending a WM_SETREDRAW via SendMessage to disable then reenable followed by an Invalidate() after I finished updating. That seemed to work.

Никогда не пробовал этот метод. Я написал приложение с RTB, которое имеет подсветку синтаксиса и использовал следующее в классе RTB:

protected override void WndProc(ref Message m)
{
    if (m.Msg == paint)
    {
        if (!highlighting)
        {
            base.WndProc(ref m); // if we decided to paint this control, just call the RichTextBox WndProc
        }
        else
        {
            m.Result = IntPtr.Zero; // not painting, must set this to IntPtr.Zero if not painting otherwise serious problems.
        }
    }
    else
    {
        base.WndProc(ref m); // message other than paint, just do what you normally do.
    }
}

Надеюсь это поможет.

WM_SETREDRAW у меня работал. Должен быть таким же, как LockWindowUpdate.

DK. 11.10.2008 00:41

Я бы посоветовал посмотреть LockWindowUpdate


[DllImport("user32.dll", EntryPoint = "LockWindowUpdate", SetLastError=true,
ExactSpelling=true, CharSet=CharSet.Auto,
CallingConvention=CallingConvention.StdCall)]

-1. Это неправильное использование. См. blogs.msdn.com/b/oldnewthing/archive/2007/02/19/1716211.aspx.

Muhammad Alkarouri 19.12.2011 14:59

Я задал исходный вопрос, и ответ, который лучше всего сработал для меня, - это использование BoltBait SendMessage () с WM_SETREDRAW. Кажется, что у него меньше побочных эффектов, чем при использовании метода WndProc, а в моем приложении он работает в два раза быстрее, чем LockWindowUpdate.

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

    private void StopRepaint()
    {
        // Stop redrawing:
        SendMessage(this.Handle, WM_SETREDRAW, 0, IntPtr.Zero);
        // Stop sending of events:
        eventMask = SendMessage(this.Handle, EM_GETEVENTMASK, 0, IntPtr.Zero);
    }

    private void StartRepaint()
    {
        // turn on events
        SendMessage(this.Handle, EM_SETEVENTMASK, 0, eventMask);
        // turn on redrawing
        SendMessage(this.Handle, WM_SETREDRAW, 1, IntPtr.Zero);
        // this forces a repaint, which for some reason is necessary in some cases.
        this.Invalidate();
    }

Есть ли шанс завершить код? Это не совсем компилируемо, как написано в настоящее время.

Dan W 15.04.2015 16:49

Ожидается вызов Invalidate (). Я использовал вариант этого в приложении MDI, где каждое из дочерних окон MDI содержало RichTextBox. В этом случае мне пришлось аннулировать управление с помощью child.richTextBox.Invalidate();.

Paul Williams 08.05.2020 04:28

Вот полный и рабочий пример:

    private const int WM_USER = 0x0400;
    private const int EM_SETEVENTMASK = (WM_USER + 69);
    private const int WM_SETREDRAW = 0x0b;
    private IntPtr OldEventMask;       

    [DllImport("user32.dll", CharSet=CharSet.Auto)]
    private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);

    public void BeginUpdate()
    {
        SendMessage(this.Handle, WM_SETREDRAW, IntPtr.Zero, IntPtr.Zero);
        OldEventMask = (IntPtr)SendMessage(this.Handle, EM_SETEVENTMASK, IntPtr.Zero, IntPtr.Zero);
    }       

    public void EndUpdate()
    {
        SendMessage(this.Handle, WM_SETREDRAW, (IntPtr)1, IntPtr.Zero);
        SendMessage(this.Handle, EM_SETEVENTMASK, IntPtr.Zero, OldEventMask);
    }

Другие вопросы по теме