Рисуем на нескольких элементах управления
Создадим такой проект (Рис. 6.8).
Рис. 6.8
Слева мы видим текстовое поле (TextBox1), посредине – графическое поле (PictureBox1), справа – кнопки (начиная с Button1 наверху и кончая Button7 внизу). Смысл кнопок во многом ясен из надписей на них.
Вот программа. Ниже – пояснения.
Public Class Form1
Inherits System.Windows.Forms.Form
Windows Form Designer generated code
'Объявляем графические объекты для формы и элементов управления:
Dim Граф_для_формы As Graphics
Dim Граф_для_текстов_поля As Graphics
Dim Граф_для_графич_поля As Graphics
Dim Граф_для_кнопки As Graphics
'Создаем графические объекты для формы и элементов управления:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Граф_для_формы = Me.CreateGraphics
Граф_для_текстов_поля = TextBox1.CreateGraphics
Граф_для_графич_поля = PictureBox1.CreateGraphics
Граф_для_кнопки = Button5.CreateGraphics
End Sub
'Рисуем на форме:
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Граф_для_формы.DrawLine(Pens.Black, 0, 0, 3000, 900)
End Sub
'Рисуем на текстовом поле:
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
Граф_для_текстов_поля.DrawRectangle(Pens.Black, 20, 20, 200, 120)
End Sub
'Рисуем на графическом поле:
Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
Граф_для_графич_поля.FillPie(Brushes.Red, 30, 30, 80, 150, 90, 330)
End Sub
'Рисуем на кнопке:
Private Sub Button5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button5.Click
Граф_для_кнопки.DrawEllipse(Pens.Black, 10, 10, 30, 30)
End Sub
'Стираем с текстового поля:
Private Sub Button6_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button6.Click
Граф_для_текстов_поля.Clear(Color.White)
End Sub
'Уничтожаем графические объекты для формы и элементов управления:
Private Sub Button7_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button7.Click
Граф_для_формы.Dispose()
Граф_для_текстов_поля.Dispose()
Граф_для_графич_поля.Dispose()
Граф_для_кнопки.Dispose()
End Sub
End Class
Пояснения. Прежде всего, я объявил графические объекты вне процедур, а не внутри. По той простой причине, что использую каждый графический объект не в одной, а в нескольких процедурах. Иначе графический объект, объявленный внутри одной процедуры, не был бы «виден» из других (подробнее о видимости переменных рассказано в 11.3).
Кнопка Button1 создает все графические объекты. Все остальные кнопки заставляют эти графические объекты что-нибудь сделать. Попробуйте, запустив проект, начать работу с нажатия не верхней кнопки, а какой-нибудь другой – VB выдаст ошибку. Действительно: нельзя заниматься графическими работами с нерожденными графическими объектами.
Смысл кнопок с Button2 по Button5 очевиден: каждая из них рисует то, что вы видите на рисунке.
Кнопка Button6 стирает. Для стирания всего, что нарисовано на объекте, существует метод Clear. В нем нужно указать цвет, которым все стирается. Этот цвет является свойством структуры Color. Я выбрал белый цвет. Можно было выбрать любой.
Если вы захотите методом Clear стереть что-нибудь на форме или другом элементе управления, то перед вами встанет вопрос, а какой цвет у этого объекта? Заглянув в окно свойств, вы увидите скорее всего, что это цвет Control. Но в структуре Color такого цвета нет! Что же делать? – Или заранее покрасить форму или элемент управления в другой цвет или почитать о системных цветах в 12.7.1.
Кнопка Button7 уничтожает все графические объекты. Каждый созданный объект, даже если он невидим, расходует ресурсы компьютера или, как нынче говорят, «напрягает» компьютер. Хорошим тоном у программистов является заботиться о компьютере и не перенапрягать его. Поэтому, когда ясно, что объект отработал свое и больше не понадобится, его уничтожают методом Dispose.
Замечания. Структура Color предлагает нам полторы сотни цветов, а окно свойств – гораздо большее количество. В 12.7 я расскажу вам, как пользоваться в коде несколькими миллионами цветов.
Обратите внимание, что рисунок в текстовом окне стирается и тогда, когда вы вручную начнете стирать в нем текст. А рисунок с кнопки стирается тогда, когда вы щелкнете по другой кнопке или по текстовому полю. Если вы, таская форму по экрану, затащите часть ее за край экрана, то все, нарисованное в этой части, сотрется. Если же форма полностью пропадет из вида, то сотрется все. О причинах этого явления и о том, как с ним бороться, написано в 12.5
Подробности о работе объекта класса Graphics. Когда объект класса Graphics создается методом CreateGraphics, он в момент создания запоминает размеры поверхности, на которой будет рисовать. Пусть, например, это форма. Размеры поверхности он запоминает как размеры формы в момент своего создания. Если же мы впоследствии изменим размеры формы, размеры поверхности рисования от этого не изменятся, что может нам не понравиться.
Это легко проверить. Запустите проект. Щелкните по первой кнопке. Объект порожден. А теперь растяните форму и щелкните по второй кнопке. На форме рисуется идущий наискосок отрезок прямой. Судя по координатам, он должен был быть очень длинным, однако он рисуется только в пределах размеров формы, какой она была при щелчке по первой кнопке.
Если вы не хотите задумываться об этой проблеме, объявляйте и создавайте графический объект прямо в той процедуре, которая рисует, как я и делал в этой книге в большинстве программ.
С учетом вышесказанного не советую создавать графический объект для формы в процедуре Form1_Load, то есть когда форма еще не появилась на экране.
Пишем
На форме и элементах управления можно не только рисовать, но и писать, то есть изображать на их поверхности текст. Вы скажете: это не новость, мы уже делали это, устанавливая свойство Text для текстового поля, метки и кнопки. Но это другое. Здесь мы будем обладать свободой писать текст в любой точке поверхности объекта и у нас будет гораздо больше возможностей для его красивого оформления (см., например, рисунки в 12.2.3). Здесь текст будет не задаваться, как мы это делали раньше, а рисоваться методами объекта класса Graphics, как мы рисуем линии, кружочки и пр.
Продолжим работу над предыдущим проектом. Добавим в него кнопку Button8 «Пишем». По нажатии на нее на поверхности формы и элементов управления должно появиться четыре слова приветствия: "Привет!", "Здравствуй!", "Салют!", "Hello!" (см. Рис. 6.9).
Рис. 6.9
Начнем с того, что в режиме проектирования изменим для кнопки Button5 свойство Font (шрифт): сделаем шрифт пожирней и побольше. Вы видите результат этого изменения на рисунке в виде текста «Рисую на себе». Аналогично немного увеличьте и сделайте курсивным шрифт текстового поля TextBox1. Но это все не то – это все вспомогательные действия в режиме проектирования. Нас интересует рисование текста в коде.
Рисованием текста занимается все тот же объект класса Graphics. Для этого он использует свой метод DrawString(«Нарисуй строку»). Как будто бы текст – это та же фигура, только поизвилистей.
Добавьте в проект следующую процедуру:
'Пишем на форме и элементах управления:
Private Sub Button8_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button8.Click
Граф_для_формы.DrawString("Привет!", Button5.Font, Brushes.Red, 70, 280)
Граф_для_текстов_поля.DrawString("Здравствуй!", Me.Font, Brushes.Brown, 50, 100)
Граф_для_графич_поля.DrawString("Салют!", Button5.Font, Brushes.White, 35, 70)
Граф_для_кнопки.DrawString("Hello!", TextBox1.Font, Brushes.Blue, 0, 0)
End Sub
Разберемся, что здесь написано.
Форма и каждый элемент управления пишут на себе своими собственными объектами класса Graphics. В том варианте метода DrawString, который я использую, в скобках вы видите 5 параметров, разделенных запятыми:
· 1 параметр – это собственно строка текста, которую вы хотите написать.
· 2 параметр – это шрифт, который мы выбираем для написания строки. Пока я еще не пояснил вам, как в коде свободно и независимо управлять шрифтом, поэтому мы будем пользоваться шрифтами, установленными в режиме проектирования. Так, мы только что в режиме проектирования установили свойства Button5.Font и TextBox1.Font. Свойство Font имеется и у формы (Me.Font), и у других элементов управления. Мы можем в коде свободно пользоваться этими шрифтами, как готовыми перьями или кистями. В процедуре вы видите, что для написания строк на форме и в графическом поле я использовал шрифт кнопки Button5, для написания строки в текстовом поле я использовал шрифт формы, а для написания строки на кнопке – шрифт текстового поля.
· 3 параметр – кисть. Да, буквы мы пишем кистью, а не пером. Цвет кисти выбираем по вкусу.
· 4 и 5 параметры – координаты места, в котором мы хотим написать текст, на форме или элементе управления. А чтобы быть более точным, вообразим, что текстовая строка заключена в тесный прямоугольник. Тогда эти два параметра – координаты верхнего левого угла этого прямоугольника относительно верхнего левого угла объекта, на котором пишем.
Пишем строковые выражения. Текстовая строка, являющаяся 1 параметром метода, может быть строковым выражением. Например, фрагмент
Dim a As Integer = 100
Dim s As String = " попугаев"
Граф.DrawString(a & " разноцветных" & s, Me.Font, Brushes.Black, 0, 0)
напишет на форме: 100 разноцветных попугаев
Свободное управление в коде параметрами шрифта отложим до 12.2.3.