События
клавиатуры
Три события
клавиатуры инициируются в тех же ситуациях, что и их аналоги из прежних версий
VB.
По аналогии
с VB6 событие KeyDown инициируется раньше события KeyPress, которое, в свою
очередь, предшествует KeyUp. Событие KeyPress использует объект KeyPressEventArgs,
в свойстве KeyChar которого передается информация о нажатой клавише. Например,
следующий фрагмент выводит окно сообщения в том случае, если введенный символ
не является цифрой:
Private Sub TextBoxl_KeyPress(ByVal sender As Object._
ByVal e As System.Windows.Forms.KeyPressEventArgs)
Handles TextBoxl.KeyPress
If e.KeyChar < "0" Or e.KeyChar > "9" Then
MsgBox("only
digits allowed")
End If
End Sub
События KeyDown
и KeyUp, как и в VB6, могут использоваться для проверки клавиш-модификаторов
(таких, как Ctrl и Alt). Класс KeyEventArgs, передаваемый этим событиям, обладает
несколько большими возможностями, чем класс KeyPressEventArgs события KeyPress.
Класс KeyEventArgs содержит свойство KeyData, в котором при помощи перечисляемого
типа Key передается полная информация о комбинациях клавиш и о состоянии клавиш-модификаторов
в момент нажатия. Свойства Modi f i ers и Shi ft позволяют узнать об одновременном
нажатии трех клавиш (Alt+ +Shift+другая клавиша). Например, следующая команда
проверяет, была ли нажата клавиша-модификатор Alt: If e.Modifiers =Keys.Alt
Then
Если
вас не интересуют такие мелочи, как различия между левой и правой клавишей Shift,
удобнее воспользоваться свойствами Control Shift и Alt класса KeyEventArgs.
К сожалению,
значения свойств KeyChar и KeyData нельзя сбросить, поскольку они доступны только
для чтения [ Возможно, этот недочет будет исправлен в окончательной версии. ].
Впрочем, введенный символ можно «поглотить» и тем самым предотвратить
его появление в элементе; для этого свойству Handled объекта события задается
значение True. Пример:
If e.KeyChar
< "0" Or e.KeyChar >"9" Then
e.Handled = True
End If
В результате
неверный символ не появится в текстовой поле.
В .NET вместо
одного события проверки существуют целых два: Validating и Validated. Событие
Validating инициируется перед утратой фокуса элементом. Например, следующий
фрагмент гарантирует, что пользователь не оставит текстовое поле пустым:
Public Sub TextBoxl_Validating(ByVa1
sender As Object.
ByVal e As System.ComponentModel.CancelEventArgs)
Handles TextBoxl.Validating
' Если текстовое поле не содержит символов, отменить передачу фокуса
If TextBoxl.Text.Trim
= String.Empty Then e.Cancel = True
End Sub
Команда e.Cancel
= True отменяет передачу фокуса от текстового поля другому элементу, если в
поле нет ни одного символа.
С другой
стороны, событие Val idated инициируется после утраты фокуса элементом, но до
передачи его другому элементу. Таким образом, в обработчике события Validated
можно обновить состояние других элементов формы.
Если
свойство CausesValidation элемента равно False, события Validating и Validated
не инициируются.
Графическое
программирование в .NET Framework полностью отличается от всего, что было реализовано
в прежних версиях VB. Знакомые графические команды (частично позаимствованные
еще из QuickBasic) исчезли. Из числа принципиальных изменений также следует
обратить внимание на отсутствие свойства AutoRedraw или его аналогов. В прежних
версиях VB свойство AutoRedraw, равное True, избавляло программиста от необходимости
программировать процедуру события Pal nt для того, чтобы обеспечить восстановление
графического изображения в элементе.
Программирование
графики в VB .NET основано на концепции графического контекста — отдаленного
родственника контекстов устройств Windows GDI. Любопытная подробность: новая
система называется GDI+, хотя с GDI она имеет очень мало общего.
У
программистов с опытом работы в GDI переход на GDI+ часто вызывает шок, поскольку
графический вывод в .NET происходит без сохранения состояния. Иначе говоря,
каждая графическая команда должна содержать полную информацию о выполняемой
операции. Скажем, если вы использовали черную кисть в первой строке программы
и хотите снова воспользоваться ею во второй строке, необходимо указать графической
системе, что операция должна выполняться черной кистью. GDI+ «не помнит»
об операциях, выполнявшихся ранее.
Классы GDI+
находятся в пространствах имен System.Drawing, System.Drawing. Drawing2D, System.
Drawing. Imagi ng и System. Drawing. Text [ Каждое из этих пространств имен
заслуживает отдельной книги, и здесь мы ограничимся лишь кратким упоминанием. ].
Эти пространства имен входят в
сборку System.Drawing, ссылка на которую создается автоматически при выборе
типа приложения Windows Application в диалоговом окне New Project.
Большая часть
графического вывода в GDI+ осуществляется переопределением процедуры [ Это
не событие, хотя в конечном счете перерисовка и приводит к |ызову события OnPaint
базового класса Form. ]OnPaint формы или элемента. Процедура OnPaint играет
столь же важную роль, как и в прежних версиях VB: она обеспечивает восстановление
изображения при временном скрытии или свертывании формы. Сигнатура этой важной
процедуры выглядит следующим образом: Protected Overrides Sub OnPaint(ByVal
e As PaintEventArgs)
Вывод осуществляется
на графической поверхности GDI+, представленной экземпляром класса Graphics.
Процедура OnPaint класса Form инкапсулирует такую поверхность в виде значения
свойства e.Graphics.
Хотя
любая форма или элемент (в том числе и PictureBox) с поддержкой вывода позволяет
получить доступ к своему графическому содержимому при помощи вызова ControlName.CreateGraphics,
будьте очень внимательны, если это происходит за пределами процедуры Paint.
Между выводом в графическом контексте, полученным вызовом e.Graphics в процедуре
OnPaint и написанием кода, использующего CreateGraphics, существуют тонкие различия.
Мы столкнулись с этой проблемой при создании программы вывода всех шрифтов (см.
ниже).
Рассмотрим
очень простой пример графического вывода. Следующая программа выводит растровый
файл sample.bmp (находящийся в каталоге \bin решения) в левом верхнем углу формы:
Protected Overrides
Sub OnPaint(ByVal e As PaintEventArgs)
MyBase.OnPaint(e)
Dim g As Graphics
g = e.Graphics()
g.Draw!mage(New
Bitmap("sample.bmp"). 0. 0)
g.Dispose()
End Sub
Обратите
внимание на вызов Dispose в строке, выделенной жирным шрифтом. Поскольку сборщик
мусора не освобождает графические контексты, привыкайте делать это самостоятельно
в конце процедуры Paint.
Напоминаем:
если объект поддерживает метод Dispose, этот метод следует вызвать по завершении
работы с объектом.
Следующий
этап — рисование линий, прямоугольников и других фигур. Перед операциями такого
рода следует получить объект пера, который является экземпляром класса System.Drawing.Pen.
Самый распространенный конструктор класса Реп имеет следующий синтаксис:
Public Sub New(Color.Single)
Первый параметр
определяет цвет пера (и входит в перечисляемый тип System. DrawingColor), а
второй определяет толщину пера (другие конструкторы также позволяют задать кисть
для заполнения внутренней части объекта). Например, чтобы нарисовать прямоугольник,
вы определяете его размеры и вызываете g. DrawRectangle. Результат выполнения
следующей программы показан на рис. 8.22:
Protected Overrides
Sub OnPaint(ByVa1 e As PaintEventArgs)
MyBase.OnPaint(e)
Dim g As Graphics
g = e.Graphics()
Dim myPen As
New PerKColor,Purple. 6)
Dim aRectangle
As New Rectangle(Me.ClientRectangle.Width \4,_
Me.ClientRectangle.Height
\ 4. . Me.ClientRectangle.Height \2,_
Me.ClientRectangle.Width
\ 2))
g.DrawRectangle(myPen,aRectangle)
g.Dispose()
End Sub
Рис.
8.22. Результат вызова DrawRectangle: прямоугольник в рамке толщиной
6 пикселов
Метод DrawString
объекта Graphics предназначен для вывода текста. При вызове этого метода задается
объект шрифта, цвет, кисть и начальная точка вывода. Например, следующий фрагмент
выводит текст «Hello World» — в современных книгах по программированию
это превратилось в традицию. При выводе используется текущий шрифт формы, текст
выводится фиолетовой кистью на белом фоне:
Protected Overrides Sub OnPaint(ByVal e As _
System.Wi ndows.Forms.PaintEventArgs)
MyBase.OnPaint(e)
Dim g As Graphics
= e.Graphics
Dim theColor
As Color = Color.Purple
Dim theFont As New Font("Arial", 22._
FontStyle.Bold
Or FontStyle.Italic)
Me.BackColor
= Col or.White
g.DrawString("Hello
World!". theFont.New SolidBrush(theColor). 0, 0)
g.Dispose()
End Sub
Рис.
8.23. Вывод текста «Hello World!» средствами GDI+
В
GDI+ полностью поддерживается кодировка Unicode, что позволяет выводить текст
на любом языке.