Моя программа рисует текст на панели, но если я хочу удалить текст, я должен перерисовать.
Как мне назначить (поднять) событие рисования вручную?
Моя программа рисует текст на панели, но если я хочу удалить текст, я должен перерисовать.
Как мне назначить (поднять) событие рисования вручную?
Метод Invalidate() вызовет перерисовку.
В методе вашей формы или элемента управления у вас есть 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, и этот цикл временно блокирует Message-Loop. Всякий раз, когда вы его используете, вы должны спросить себя, не следует ли вместо этого использовать Thread. Но ответ всегда есть.
Я обнаружил, что 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 и событие paint будут подняты.
Обновление, возможно, также сделает для гораздо более читаемого кода, в зависимости от контекста.
используйте Control.InvokePaint
, вы также можете использовать его для ручной двойной буферизации