События клавиатуры

Три события клавиатуры инициируются в тех же ситуациях, что и их аналоги из прежних версий VB.

  • KeyPress: происходит при нажатии клавиши, когда элемент обладает фокусом.
  • KeyDown: происходит при переходе клавиши в нажатое состояние, когда элемент обладает фокусом.
  • Key Up: происходит при отпускании клавиши, когда элемент обладает фокусом.
  • По аналогии с 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 не инициируются.

     

    Графика: GDI+

    Графическое программирование в .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, что позволяет выводить текст на любом языке.