Как я могу назвать событие краски?
Моя программа рисует текст на своей панели, но если я хочу удалить текст, мне нужно перекрасить.
Как мне вызвать (поднять) событие рисования вручную?
7 ответов
В методе вашей Формы или Контроля у вас есть 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);
}
Этот подход может быть неприменим ко всем ситуациям, но пока он мне подходит.
Вызовите control.invalidate и событие рисования будет инициировано.
Обновление, вероятно, также сделает код более читабельным, в зависимости от контекста.
Может быть, это старый вопрос, и именно поэтому эти ответы у меня не сработали... используя Visual Studio 2019, после некоторого исследования я нашел следующее решение:
this.InvokePaint(this, new PaintEventArgs(this.CreateGraphics(), this.DisplayRectangle));
Использование Control.InvokePaint
Вы также можете использовать его для ручной двойной буферизации