Динамическая обработка событий
Основной проблемой синтаксиса WithEvents является его недостаточная гибкость. Обработчики событий нельзя динамически устанавливать и отключать на программном уровне – фактически вся схема обработки событий жестко фиксируется в программе. Однако в VB.NET поддерживается другой способ динамической обработки событий, значительно более гибкий. Он основан на возможности указания процедуры класса-приемника, вызываемой при возникновении события (исключение добавленных обработчиков также происходит динамически).
Конечно, для установки обработчика события необходимо зарегистрировать не только класс-приемник, но и метод, который должен вызываться при возникновении события. Для этой цели применяется команда AddHandler, которой при вызове передаются два параметра:
- имя события в классе-источнике;
- адрес метода (процедуры событий) класса-приемника, вызываемого при возникновении события.
Код AddHandlег включается в класс-приемник, а не в класс-источник. Адрес метода, вызываемого при возникновении события, определяется оператором AddressOf. При вызове AddressOf передается имя метода объекта класса-приемника. Например, следующая команда устанавливает динамический обработчик события для объекта:
tom: AddHandler tom.SalarySecurityEvent.AddressOf anEmp1oyee_SalarySecurityEvent
В результате тестовая программа будет обнаруживать событие SalarySecurityEvent объекта tom и в случае его возникновения – вызывать процедуру anEmployee_SalarySecurityEvent текущего модуля (разумеется, процедура anEmployee_SalarySecurityEvent должна обладать правильной сигнатурой!).
Ниже приведен фрагмент решения AddHandlerExamplel:
Module Modulel
Private WithEvents anEmployee As EmployeeWithEvents Sub Main()
Dim torn As New EmployeeWithEvents("Tom". 100000)
Console.WriteLine(tom.TheName & "has salary " & tom.Salary)
AddHandler tom.SalarySecurityEvent,
AddressOf anEmployee_SalarySecurityEvent
tom.RaiseSalary(0.2D) ' Суффикс D – признак типа Decimal
Console.WriteLine(tom.TheName & "still has salary " & tom.Salary)
Console.WriteLine("Please press the Enter key")
Console. ReadLine()
End Sub
Public Sub anEmployee_SalarySecurity£vent(ByVal Sender _
As AddHandlerExamplel.EmployeeWi thEvents,_
ByVale As AddHandlerExamplel.ImproperSalaryRaiseEvent)_
Handles anEmployee.SalarySecurityEvent
MsgBox(Sender.TheName & "had an improper salary raise of " & _
FormatPercent(e.theRaise) & "with INCORRECT PASSWORD!")
End Sub
End Module
Команда AddHandler обладает просто невероятной гибкостью. Например, установка обработчиков событий может зависеть от имени типа:
If TypeName(tom)="Manager" Then AddHandler tom.SalarySecurityEvent.AddressOf _ anEmployee_SalarySecurityEvent e End If
Кроме того, один обработчик событий можно связать с несколькими разными событиями, происходящими в разных классах. Это позволяет выполнять в VB.NET централизованную обработку событий с динамическим назначением обработчиков – в VB такая возможность встречается впервые. В приведенном ниже листинге инициируются разные события в зависимости от переданных параметров командной строки. Главное место в нем занимают фрагменты вида:
Case "first" AddHandler m_EventGenerator.TestEvent,_ AddressOf m_EventGenerator_TestEventl
При передаче в командной строке аргумента first устанавливается соответствующий обработчик события.
