Как я могу назвать событие краски? - PullRequest
44 голосов
/ 05 июня 2009

Моя программа рисует текст на своей панели, но если я хочу удалить текст, мне нужно перекрасить.

Как мне вызвать (поднять) событие рисования вручную?

Ответы [ 7 ]

86 голосов
/ 05 июня 2009

В методе вашей Формы или Контроля у вас есть 3 варианта:

this.Invalidate();  // request a delayed Repaint by the normal MessageLoop system    
this.Update();      // forces Repaint of invalidated area 
this.Refresh();     // Combines Invalidate() and Update()

Обычно вы просто звоните Invalidate() и позволяете системе объединить это с другими обновлениями экрана. Если вы спешите, вы должны позвонить Refresh(), но тогда вы рискуете, что он будет перекрашиваться несколько раз подряд из-за аннулирования других элементов управления (особенно родительского).

Обычный способ, которым Windows (Win32 и WinForms.Net) обрабатывает это, - это дождаться, пока MessageQueue не запустится, и затем обработать все недействительные области экрана. Это эффективно, потому что когда что-то меняется, что обычно каскадно переходит в другие вещи (элементы управления).

Наиболее распространенный сценарий для Update () - это когда вы изменяете свойство (скажем, label1.Text, которое сделает недействительным Label) в цикле for, и этот цикл временно блокирует цикл обработки сообщений. Всякий раз, когда вы используете его, вы должны спросить себя, не следует ли вместо этого использовать поток. Но ответ не всегда да.

42 голосов
/ 05 июня 2009

Метод Invalidate () вызовет перерисовку.

MSDN Link

6 голосов
/ 08 декабря 2013

Я обнаружил, что Invalidate () создает слишком много мерцания. Вот моя ситуация. Разрабатываемый мной пользовательский элемент управления рисует все содержимое путем обработки события Paint .

this.Paint += this.OnPaint;

Этот обработчик вызывает пользовательскую подпрограмму, которая выполняет фактическое рисование.

private void OnPaint(object sender, PaintEventArgs e)
{
    this.DrawFrame(e.Graphics);
}

Для имитации прокрутки я хочу перекрашивать свой элемент управления каждый раз, когда курсор перемещается, пока нажата левая кнопка мыши. Мой первый выбор - использовать Invalidate () , как показано ниже.

private void RedrawFrame()
{
    var r = new Rectangle(
        0, 0, this.Width, this.Height);

    this.Invalidate(r);
    this.Update();
}

Управление прокручивается нормально, но мигает далеко за пределы любого комфортного уровня. Поэтому я решил вместо перерисовки элемента управления вызывать свой метод DrawFrame () непосредственно после обработки события MouseMove . Это произвело плавную прокрутку без мерцания.

private void RedrawFrame()
{
    var g = Graphics.FromHwnd(this.Handle);
    this.DrawFrame(g);
}

Этот подход может быть неприменим ко всем ситуациям, но пока он мне подходит.

5 голосов
/ 05 июня 2009

Я думаю, что вы также можете позвонить Refresh().

4 голосов
/ 05 июня 2009

Вызовите control.invalidate и событие рисования будет вызвано.

3 голосов
/ 05 июня 2009

Обновление, вероятно, также сделает код более читабельным, в зависимости от контекста.

0 голосов
/ 28 марта 2017

использовать Control.InvokePaint вы также можете использовать его для ручной двойной буферизации

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...