Перерисовка картинок, фигур и текста
Вы, наверное, давно уже обратили внимание на такой факт. Если форма с нарисованными фигурами, картинками или написанным текстом скрывается из глаз, закрытая другими окнами, то когда мы вновь ее добываем из-под других окон, то видим, что нарисованные картинки, фигуры и текст стерлись. Если мы часть формы затащили за край экрана, то стирается все, что было нарисовано и написано на этой скрывшейся за край экрана части. Если мы мышью уменьшили размеры формы, а потом снова увеличили, то на поверхности, обнажившейся после увеличения, все стерто. В общем, стирается все то, что пропадает с глаз.
Но если картинка находится на элементе управления в качестве его свойства Image, то она не стирается. Стирается лишь то, что нарисовано.
Чтобы стирания нарисованных вещей не происходило, в Visual Basic 6.0 мы просто в режиме проектирования устанавливали у формы свойство AutoRedraw, и могли больше об этом не думать. Однако VB слишком сложен и мощен для такого «детского» решения.
Посмотрим, что нужно делать в VB.
Событие Paint. В каком случае мы можем заметить, что на форме что-то стерто? Наверное, тогда и только тогда, когда в поле нашего зрения на экране появляется участок формы (пусть даже самый маленький), который был до этого по той или иной причине скрыт (и поэтому с него все было стерто).
Задача VB – создать у нас иллюзию, что ничего не стирается. Для этого путь один – как только такой участок со стертой информацией возникает в поле зрения, тут же его снова зарисовывать «как было», чтобы человек не успевал ничего заметить. Однако, сам VB зарисовывать ничего не собирается, он предоставляет позаботиться об этом программисту. Для чего в помощь ему VB отряжает событие Paint. Это событие наступает как раз тогда, когда в поле зрения на экране появляется участок формы (пусть самый ничтожный), который был до этого скрыт. Если вы, например, медленно вытаскиваете форму из-за края экрана или медленно увеличиваете ее высоту или ширину, то каждую ничтожную долю секунды в поле зрения появляются «стертые» участки, а значит, наступает событие Paint. Получается, что в данном случае событие Paint наступает много раз в секунду.
Раз есть событие, значит есть и процедура-обработчик этого события. Все, что должен сделать программист, это получить в окне кода обычным способом заготовку этой процедуры и записать в нее операторы рисования всех фигур и всего текста на форме, которые он хочет предохранить от стирания. По принципу: если забор в одном месте запачкался – перекрашивай весь забор.
Создайте проект с кнопкой. Введите в окно кода такой текст:
Dim Гр As Graphics = Me.CreateGraphics
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Гр.DrawEllipse(Pens.Black, 20, 20, 80, 100)
End Sub
Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) _
Handles MyBase.Paint
Гр.DrawRectangle(Pens.Black, 10, 10, 200, 100)
End Sub
Пояснения. При нажатии на кнопку рисуется кружок. Чтобы создать заготовку процедуры-обработчика события Paint, выберите, если вы работаете в Visual Studio .NET 2003, в левом поле окна кода Form1 Events, а если в Visual Studio .NET – Base Class Events., а в правом – Paint. Введите в эту процедуру оператор рисования квадрата.
Запустите проект. Вы видите, что квадрат уже на форме, несмотря на то, что никаких кнопок вы не нажимали. Произошло это потому, что событие Paint уже успело сработать при появлении формы на экране. Щелкните по кнопке Button1. Появился еще и кружок. Теперь задвиньте форму частично за левый край экрана и снова выдвиньте. Вы увидите, что часть кружка стерта, а квадрат как будто и не стирался (см. Рис. 12.16).
Рис. 12.16
На самом деле он прекрасно стерся, но при выдвижении формы из-за края экрана много раз в секунду наступало событие Paint и он каждый раз рисовался снова. Причем рисовался настолько быстро, что человеческий глаз не успевал этого заметить.
Итак, мы видим, что власть над тем, каким фигурам стираться, а каким нет, находится полностью в руках программиста. Поэтому, если вы хотите, чтобы фигуры не стирались, помещайте операторы для их рисования в обработчик события Paint.
Событие Paint имеется не только у формы, но и у элементов управления. Можете проверить его, например, на метке.
Мы можем искусственно вызвать событие Paint и, значит, перерисовку поверхности формы или элемента управления, применяя их метод Refresh. Например, так:
Me.Refresh()
Кроме обработки события Paint VB предлагает и другие способы перерисовки, но мы на них останавливаться не будем.
Image не стирается. Очевиден такой способ борьбы со стиранием. Мы рисуем все, что нам нужно, в памяти на объекте Bitmap, а затем присваиваем получившийся Bitmap свойству Image элемента управления.