Снова
о простой программе
В главе 1
был приведен довольно сложный код Windows-приложения, автоматически сгенерированный
IDE. Приложение выполняло простейшую функцию — оно реагировало на нажатие кнопки.
Тогда же мы пообещали, что вскоре вы поймете, как работает эта программа. Настало
время вернуться к старому примеру (последовательность действий при построении
этого приложения описана в главе 1). Прежде всего обратите внимание на то, что
при построении приложений на базе форм Windows VS .NET IDE автоматически включает
в решение ссылки на сборки System.Drawing и System.Windows.Forms; в этом нетрудно
убедиться при помощи Object Browser (рис. 8.8). Сборка System.Drawing состоит
из одного пространства имен, классы которого предназначены для изменения размеров
и позиционирования форм и элементов. Кроме того, эта сборка используется при
выводе или размещении на форме графических изображений. Сборка System.Windows.Forms
тоже состоит из одного пространства имен и содержит классы всех элементов управления,
а также класс Wi ndows. Forms. Form, представляющий экземпляры форм.
Рис.
8.8. Простейшее Windows-приложение в программе Object Browser
1 Public Class
Forml
2 Inherits System.Windows.Forms.Form
3
4 IRegion "Windows
Form designer generated code "
5
6 Public Sub
New()
7 MyBase.New()
8
9 ' Вызов необходим
для работы дизайнера форм Windows
10 InitializeComponent()
11
12 ' Дальнейшая
инициализация выполняется
13 ' после вызова
InitializeComponent()
14 End Sub
15
16 ' Форма переопределяет
Dispose для очистки списка компонентов.
17 Protected
Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
18 If disposing
Then
19 If Not (components
Is Nothing)Then
20 components.Dispose()
21 End If
22 End If
23 MyBase.Dispose(disposing)
24 End Sub
25 Friend WithEvents
Buttonl As System.Windows.Forms.Button
26
27 ' Необходимо
для работы дизайнера форм Windows
28 Private components
As System.ComponentModel.Container
29
30 ' ВНИМАНИЕ:
следующий фрагмент необходим для дизайнера форм Windows
31 ' Для его
модификации следует использовать дизайнер форм.
32 ' Не изменяйте
его в редакторе!
33 <System.Diagnostics.DebuggerStepThrough()Private Sub
InitializeComponent()
34 Me.Buttonl
= New System.Windows.Forms.Button()
35 Me.SuspendLayout()
36.
37 'Button1
38
39 Me.Buttonl.Anchor = ((System.Wi ndows.Forms.AnchorStyles.Bottom Or _
System.Windows.Forms.AnchorStyles.Left) Or _
System.Windows.Forms.AnchorStyles.Right)
40 Me.Buttonl.Location
= New System.Drawing.Point(46.216)
41 Me.Buttonl.Name
= "Buttonl"
42 Me.Buttonl.Size
= New System.Drawing.Size(200.48)
43 Me.Buttonl.Tablndex
= 0
44 Me.Buttonl.Text
= "Click me!"
45'
46 'Form1
47'
48 Me.AutoScaleBaseSize
= New System.Drawing.Size(6,15)
49 Me.ClientSize
= New System.Drawing.Size(292,268)
50 Me.Controls.AddRangetNew
System.Wi ndows.Forms.Control(){Me.Buttonl})
51 Me.Name ="Form1"
52 Me.Text =
"First Windows Application"
53 Me.ResumeLayouUFalse)
54
55 End Sub
56
57 #End Region
58
59 Private Sub Buttonl_Click(ByVal sender As System.Object.ByVal e As _
System.EventArgs)Handles
Buttonl.Click
60 MsgBox("Thanks
for clicking!")
61 End Sub
62 End Class
Из строк
1 и 2 видно, что перед нами открытый (Public) класс, производный от класса Form
пространства Имен System.Windows. Forms. Знак # в строке 4 отмечает на- чалорегиона
в автоматически сгенерированном коде. Помните, что при любых операциях в
окне свойств или перетаскивании элементов в дизайнере генерируется программный
код. По мере накопления опыта вы научитесь просматривать этот код и редактировать
его.
В строках
6 и 7 начинается конструктор класса. Как обычно, в начале конструктора производного
класса вызывается конструктор базового класса (за дополнительной информацией
по этой теме обращайтесь к разделу «Иерархия классов пространства имен
System.Windows.Forms» этой главы).
В строке
10 вызывается метод Initial izeComponent, определяемый в строках 33-35. Этот
метод генерируется автоматически и преобразует в программный код все ваши действия
на стадии конструирования и в окне свойств. Например, кнопка объявляется в строке
25; позже ее экземпляр создается в строке 34, а размещение кнопки на форме происходит
в строке 50. Также обратите внимание на то, как в строках 44 и 52 программа
задает свойство Text кнопки и формы в соответствии с данными, введенными в окне
свойств.
Свойство
Text в VB .NET заменяет свойство Caption, использовавшееся в предыдущих версиях
VB.
В строках
40 и 42 методы пространства имен System. Drawl ng задают позицию и размеры кнопки,
а в строках 48-49 аналогичные действия выполняются для формы. По умолчанию единицей
измерения в графических операциях являются пикселы (!), а не твипы (twips).
Хотя
старые свойства Left, Top, Width и Height по-прежнему поддерживаются, теперь
удобнее работать со свойствами Location и Size. Свойство Location задает или
возвращает структуру Point с информацией о точке. Свойство Size использует структуру
System.Drawing.Size для хранения информации о прямоугольной области. Поскольку
каждый из этих классов просто инкапсулирует два целых числа, в них предусмотрены
свойства для задания отдельных компонентов (например, свойства Width для объекта
Size и свойства Y для свойства Point).
В строках
17-24 реализуется версия метода Dispose, необходимого для приложений на базе
форм Windows. Формат этого метода несколько отличается от простого метода Dispose,
описанного в главе 5; в данном примере освобождаются все ресурсы, используемые
всеми элементами формы, а также самой формой.
В строке
25 используется уже знакомый синтаксис (см. главу 6), указывающий на то, что
кнопка является источником событий. Непосредственное подключение обработчика
происходит в строках 59-61 с ключевым словом Handles. Синтаксис всех автоматически
сгенерированных событий элементов и форм в .NET аналогичен приведенному в строке
59:
Sub ObjectName_eventname(ByVal sender As Object.Byval e As EventArgs)_
Handles ObjectName.eventname
В параметре
sender передается ссылка на элемент, инициировавший событие. В параметре EventArgs
инкапсулируется описание события (при таких событиях, как KeyPress или MouseDown,
используются объекты классов, производных от EventArgs, — такие, как KeyEventArgs
и MouseEventArgs; в них передается дополнительная информация).
Приложение
на базе форм Windows можно запустить из процедуры Sub Main, являющейся точкой
входа вашего приложениях. При этом вызывается метод Application.Run, которому
передается имя формы:
Pubic Sub Main()
Dim myForm As
New Forml()
Application.Run(myForm)
End Sub
(Замаскированный
вызов Application.Run присутствует везде, где форма используется в качестве
стартового объекта. Интересная подробность: этот вызов обязателен в С#, но не
в VB .NET.)
Вызов
MsgBox в строке 60 характерен для программистов с большим стажем работы на VB.
В пространство имен Windows.Forms входит класс MessageBox, по своим возможностям
значительно превосходящий команду MsgBox, но старые привычки берут свое. Обратитесь
к документации по этому классу, если вы предпочитаете работать с ним.
Ограниченный
объем книги не позволяет нам рассмотреть все свойства класса Form, но мы хотим
выделить существенные различия между поведением форм в прежних версиях VB и
VB .NET. Одно из самых принципиальных изменений связано с использованием шрифтов.
Вместо старых шрифтовых свойств (например, FontBold) используется класс Font
пространства имен System.Drawing, самый распространенный конструктор которого
выглядит следующим образом:
Sub New(ByVal family As FontFamily.ByVal emSize As Single._
ByVal style As
FontStyle)
Термин «семейство
шрифтов» (font family) хорошо знаком пользователям Word. Семейством называется
группа шрифтов (Times New Roman, Courier New, Arial и т. д.), объединенных сходным
графическим стилем, но обладающих разным кеглем и атрибутами начертания (курсив,
жирный шрифт и т. д.).
Например,
поскольку оператор Or объединяет значения отдельных битов, следующая команда
присваивает переменной MyFont объект полужирного курсивного шрифта Arial с кеглем
12 пунктов:
myFont =New System.Drawing.Font("Arial". 12._
FontStyle.Bold
Or FontStyle.Italic)
Следующая
процедура события Button 1_C1ick изменяет шрифт при нажатии кнопки:
Private Sub
Buttonl_Click(ByVal sender As System.Object. _
ByVal e As System.EventArgs)
Handles Buttonl.Click
Dim myFont As
System.Drawing.Font
myFont = New
System.Drawing.Font("Arial".12.
FontStyle.Bold
Or FontStyle.Italic)
Me.Font = myFont
End Sub
На рис. 8.9
показано, как выглядит новый шрифт на кнопке.
Рис.
8.9. Кнопка с текстом, оформленным полужирным курсивным шрифтом
При
изменении свойства Font формы новый шрифт автоматически используется для вывода
свойства Text всех элементов, расположенных на форме. Исключение составляют
элементы, которым были назначены собственные шрифты.
В сочетании
со свойствами Anchor и Dock часто используются свойства MinimumSize и MaximumSize,
определяющие соответственно минимальные и максимальные размеры формы. Значения
этих свойств представляют собой объекты Size. Например,
следующая команда запрещает уменьшать форму до размеров, меньших размеров кнопки:
Me.MimmumSize
=New Size(Buttonl.Size)
Поскольку
свойство MinimumSize управляет изменением свойства Size, в заданные размеры
включается размер заголовка окна. Таким образом, после выполнения предыдущей
команды в уменьшенном окне почти не останется места для кнопки. Лучше воспользоваться
командой вида
Me.MinimumSize
= New Size(Buttonl.Size.Width * 2, Button1.Size.Height * 2)
При
изменении свойства MaximumSize часто используется класс System.Windows. Forms.Screen,
предназначенный для работы с экранами (с поддержкой нескольких мониторов). Этот
класс также используется при изменении свойств DesktopBounds и DesktopLocation.
Новое свойство
ClientSi ze возвращает информацию о клиентской области формы (области, не включающей
заголовок и рамку). Свойство Bounds предназначено для чтения/записи структуры
Rectangle, содержащей ширину и высоту формы и позицию ее левого верхнего угла.
Класс
Rectangle пространства имен System.Drawing содержит немало полезных мето-дов;
подробное описание этой вспомогательной структуры данных приведено в документации.
Мы часто используем метод Inflate, предназначенный для увеличения прямоугольников
с заданным приращением.
Многие свойства,
методы и события форм отличаются от своих прототипов из VB6. Важнейшие изменения
перечислены в табл. 8.1.
Таблица
8.1. Изменения в свойствах, методах и событиях форм
Старый элемент
формы |
Новый элемент
формы |
Activate/Deactivate
(события) |
Переименованы
в Activated/Deactivated |
Container (свойство) |
Переименовано
в Parent |
DblClick (событие) |
Переименовано
в DoubleClick |
hWnd (свойство) |
Переименовано
в Handle |
MouseCursor
(свойство) |
Переименовано
в Cursor и возвращает экземпляр класса Cursor |
Parent (свойство) |
Заменено методом
FindForm |
Picture (свойство) |
Заменено свойством
Backgroundlmage |
SetFocus (метод) |
Переименован
в Focus |
Startup (свойство) |
Заменено свойством
StartPosition |
ToolTip (свойство) |
Заменено элементом
ToolTip, который связывается с элементами через свойство ToolTip элемента |
Unload (команда)
Unload (событие) |
Заменена методом
Close Заменено событием
hosing (также существует новое событие Closed, инициируемое после
закрытия формы) |
ZOrder (метод) |
Заменен методами
BriflgToFront и SendToBack |