Как я могу назвать событие краски?

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

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

7 ответов

Решение

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

MSDN Link

В методе вашей Формы или Контроля у вас есть 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, которое сделает недействительным метку) в цикле for, и этот цикл временно блокирует цикл обработки сообщений. Всякий раз, когда вы используете его, вы должны спросить себя, не следует ли вместо этого использовать поток. Но ответ не всегда да.

Я обнаружил, что 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);
}

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

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

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

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

Может быть, это старый вопрос, и именно поэтому эти ответы у меня не сработали... используя Visual Studio 2019, после некоторого исследования я нашел следующее решение:

this.InvokePaint(this, new PaintEventArgs(this.CreateGraphics(), this.DisplayRectangle));

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

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