Моя программа рисует текст на панели, но если я хочу удалить текст, я должен перерисовать.Как мне назвать событие рисования?
Как я могу позвонить (поднять) событие рисования вручную?
Моя программа рисует текст на панели, но если я хочу удалить текст, я должен перерисовать.Как мне назвать событие рисования?
Как я могу позвонить (поднять) событие рисования вручную?
Метод Invalidate() вызовет перерисовку. будет поднят
Вызов control.invalidate и событие краски.
Думаю, что вы также можете позвонить Refresh()
.
Спасибо, Брайан. Отлично. –
В способе вашей формы или элемента управления, у вас есть 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. Но ответ всегда есть.
Я хотел бы уточнить. Update() немедленно перекрасит любую часть элемента управления, который уже недействителен. Вы все равно должны сначала аннулировать действие. Refresh() аннулирует и сразу перерисовывает весь элемент управления. Когда я пишу элемент управления, который делает свой собственный чертеж, я вызываю Invalidate() с грязным прямоугольником, а затем вызываю Update() для удобства реагирования и избегаю Refresh() ради производительности. – snarf
Обратите внимание, что может быть огромная разница в производительности процессора в зависимости от того, какой метод вы используете. 'this.Invalidate()' требует наименьших ресурсов ЦП, поскольку вы не заставляете вещи за пределами стандартного цикла сообщений, и это особенно верно, если вы можете вызывать 'this.Invalidate (false)', поэтому вы вызываете только 'OnPaint ') 'на основной элемент управления/формы, а не на дочерние элементы управления. Для одного из моих UserControls, переместившись с 'this.Update()' на 'this.Invalidate (false)' уменьшила нагрузку на процессор в 4 раза. –
Refresh, вероятно, также сделает для гораздо более читаемого кода, в зависимости от контекста.
Я нашел 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);
}
Этот подход может быть неприменим ко всем ситуациям, но до сих пор он мне подходит.
+1 для 'this.Invalidate (r)' –
Будьте осторожны, я подумайте, что результат FromHwnd() должен быть удален снова (поместите его в 'using() {}') –
Используйте двойную буферизацию, чтобы избавиться от мерцания. – TheRealChx101
использование Control.InvokePaint
вы можете также использовать его для ручной двойной буферизации
частная пустота Form1_Paint (объект отправителя, System.Windows.Forms.PaintEventArgs е) { System.Drawing.Graphics графика = this.CreateGraphics(); System.Drawing.Rectangle rectangle = новый System.Drawing.Rectangle (0, 0, 50, 50); graphics.DrawEllipse (System.Drawing.Pens.Black, прямоугольник); graphics.DrawRectangle (System.Drawing.Pens.Red, прямоугольник); } Когда этот метод краски вызван, чтобы перерисовать форму. Он перерисовывает форму, не так ли. –