Первый способ обработки событий: WithEvents и Handles
Это самый простой и короткий способ.
Когда мы в режиме проектирования помещаем элемент управления на форму и хотим написать для него обработчик какого-нибудь из его событий, то VB привычным образом помогает нам получить в окне кода заготовку обработчика (3.11): в поле, расположенном в верхней левой части окна кода, мы выбираем этот элемент управления, а в поле, расположенном в верхней правой части окна кода, мы выбираем нужное событие этого элемента. А что делать, если элементы управления помещены на форму программным путем? – То же самое, но с одним маленьким предварительным дополнением в программе.
Создайте проект из одной формы, без кнопок. Введите такой код:
Dim WithEvents
b As New Button 'Создаем кнопку
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.Controls.Add(b) 'Добавляем созданную кнопку в коллекцию формы
End Sub
Запустите проект. Вы видите, что на форме присутствует кнопка без надписи. Щелкните по ней – ничего не происходит.
Пояснения: Первая строка рождает кнопку, третья – размещает ее на форме. Слово WithEvents переводится «с событиями». Имеется в виду, что здесь кнопка рождается с возможностью обработки событий. Но обработчиков мы ведь пока не написали.
В подтверждение слов о возможности обработки событий загляните в поле, расположенное в верхней левой части окна кода. Вы увидите, что там появился элемент b. Остается только выбрать в поле, расположенном в верхней правой части окна кода, нужное событие этого элемента. Выберем Click. В окне кода появится привычная заготовка процедуры-обработчика:
Private Sub b_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles b.Click
End Sub
Напомню, что завершается заголовок обработчика словами Handles b.Click. Слово Handles переводится «обрабатывает», выражение b.Click – это событие Click объекта b. Получается, что обработчик «обрабатывает событие Click объекта b». Наличие слова Handles заставляет процедуру запускаться в тот самый момент, когда возникает событие b.Click. Если мы сотрем слова Handles b.Click, обработчик превратится в обычную процедуру пользователя и на события реагировать не будет.
Запишем в тело обработчика две простейшие строки:
Private Sub b_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles b.Click
b.Text = "Нажали"
b.Left = b.Left + 30
End Sub
Запустите проект. Щелкните по кнопке – она прыгнет направо на 30 пикселей и на ней появится надпись «Нажали».
Параметры обработчика. В нашем случае обработчику положено иметь два параметра: Первый (с именем sender) имеет тип Object и указывает на объект, с которым произошло событие (у нас это кнопка b). Второй параметр (с именем e) указывает на объект, который должен содержать полезную информацию о событии (правда, в нашем случае это объект типа EventArgs, который такой информации, к сожалению, не содержит).
Перепишем тело обработчика:
Private Sub b_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles b.Click
sender.Text = "Нажали"
sender.Left = sender.Left + 30
End Sub
Действие обработчика не изменилось, однако он стал более универсальным. Теперь по какому бы подходящему объекту не щелкнули, он прыгнет направо, надо только в заголовке процедуры после Handles изменить имя b на имя этого объекта.
Мы можем из соображений удобства как угодно переименовывать оба параметра в скобках и название процедуры перед скобками, действие обработчика от этого не изменится. Можно также убрать из типа параметров лишнее упоминание пространства имен System:
Private Sub Обработчик_нажатия_на_кнопку(ByVal На_кого_нажали As Object, _
ByVal Информация
As EventArgs) Handles b.Click
На_кого_нажали.Text = "Нажали"
На_кого_нажали.Left = На_кого_нажали.Left + 30
End Sub
Несколько обработчиков у одного события. Перепишите обработчик, а затем скопируйте, чуть-чуть изменив его имя и тело. Теперь у вас в коде – два обработчика:
Private Sub b_Click (ByVal sender As Object, ByVal e As EventArgs) Handles b.Click
MsgBox("Сработал 1-й обработчик")
End Sub
Private Sub b_Click1 (ByVal sender As Object, ByVal e As EventArgs) Handles b.Click
MsgBox("Сработал 2-й обработчик")
End Sub
Запустите проект. Щелкните один раз по кнопке – у вас последовательно появятся два сообщения. Таким образом, вы можете писать несколько обработчиков с разными именами для одного события, все они будут запускаться один за другим в результате наступления события.
Используем информацию о событии. Вспомним материал 14.2.2 о событиях мыши. Создадим такой обработчик вместо предыдущих:
Private Sub Обработчик_нажатия_на_кнопку(ByVal На_кого_нажали As Object, _
ByVal Информация As MouseEventArgs) Handles b.MouseDown
На_кого_нажали.Left = На_кого_нажали.Left + 30
If Информация.Button = MouseButtons.Left Then На_кого_нажали.Text = "Левая"
If Информация.Button = MouseButtons.Right Then На_кого_нажали.Text = "Правая"
End Sub
Обработчик обрабатывает событие b.MouseDown и пользуется информацией из объекта типа MouseEventArgs. Надпись на кнопке меняется в зависимости от того, какую клавишу мыши мы нажали.
Если вы хотите, вы можете в выражении, стоящем после слова Handles, стереть событие MouseDown, вам тут же будет предложен на выбор список всех возможных событий элемента b. Выберите подходящее другое – и обработчик будет обрабатывать уже его (о том, какие события будут подходящими, написано чуть ниже). Вы можете даже стереть b, вам тут же будет предложен на выбор список всех возможных элементов, порождающих события.
Один обработчик для нескольких событий. Одним обработчиком можно обрабатывать события разных объектов, причем и события тоже могут быть разные. Создайте проект без кнопок. Запишите такой код:
Dim WithEvents b1, b2, b3 As New Button
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.Controls.Add(b1)
Me.Controls.Add(b2)
Me.Controls.Add(b3)
End Sub
Private Sub Обработчик_событий_кнопки(ByVal Кнопка As Object, _
ByVal Информация As EventArgs) Handles b1.Click, b2.Click, b3.MouseEnter
Кнопка.Left = Кнопка.Left + 30
End Sub
После запуска проекта вы сможете гонять по форме три кнопки: две щелчками, а одну – просто вхождением мышиного курсора на ее поверхность.
Не любые события можно перечислять через запятую в заголовке обработчика, а лишь те, для обработки которых подходят параметры именно тех типов, что указаны в скобках. Какие именно типы параметров подходят, вы узнаете, поставив текстовый курсор на название события (например, MouseEnter) и нажав F1. В появившемся окне помощи щелкните по слову EventHandler. Вы увидите шаблон с указанием параметров.
К сожалению, словом WithEvents нельзя объявлять массив объектов.