|
|||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||
|
Проста
ініціація подій
Давайте повернемося
до простого класу Empl oyee і детально, крок за кроком розберемо все, що необхідно
зробити для визначення і ініціації подій. Припустимо, подія повинна
ініціюватися при спробі збільшення заробітної плати більш ніж на 10 відсотків
без введення пароля. В розділі 4 метод Raisesalary виглядав так: Public Overloads Sub Raisesalary(Byval percent As Decimal) If percent >
LIMIT Then '
Операція заборонена - Необхідний пароль Console.WriteLine("MUST
HAVE PASSWORD TO RAISE SALARY " & _ "MORE THAN
LIMIT!!!!") Else m_sa1ary =(1 + percent) * m_salary End If End Sub Замість виділеної команди,
що виводить текстове повідомлення на консоль, повинна ініціюватися подія.
Завдання вирішується у декілька етапів. У простому випадку в класі спочатку оголошується
відкрита змінна з ключовим словом Event, з вказівкою імені події
і його параметрів. Наприклад, наступний рядок вельми близький до синтаксису Vb6:
Public Event Salarysecurityeventdnessage as String) У цьому рядку оголошується
відкрита подія з параметром строкового типу. Після того, як
змінна події буде визначена, подія ініціюється командою наступного вигляду
(втім, для того, щоб подія дійсно відбулася, буде потрібно
ще деякі додаткові дії): Raiseevent Salarysecurityeventc'must HAVE PASSWORD TO RAISE " & _ "Salary
MORE THAN LIMIT!! !!")
Проте з цього не виходить, що для будь-якої події слід обмежуватися
одним строковим параметром. Відповідно до парадигми програмування .NET як параметри
будь-якої події передається об'єкт-джерело і інформація про подію, інкапсульована
в об'єкті події. На перших порах цілком достатньо оголошення вигляду Public Event
Salarysecurityevent(Byval who As Employee, Byvale As system.EventArgs) Подія ініціюється наступною командою Raiseevent: Raiseevent
Salarysecurityevent(Me,new System.EventArgs()) По сигнатурі
події приймач дізнається, від якого джерела поступила подія (у даному прикладі
це об'єкт-працівник, якому спробували неправильно підвищити заробітну плату);
сам об'єкт передається у вигляді ключового слова Me. Впро
чим, приведене оголошення не використовує можливостей передачі даних в
змінній події е. Незабаром ми розробимо клас, похідний від System. Eventargs,
в об'єктах якого міститиметься рядок попередження разом з даними про
спробу підвищення заробітної плати.
Підключення
приймачів до джерела
У нашому розпорядженні
є весь код, необхідний для розсилки подій, але поки немає жодного зацікавленого одержувача.
Існує декілька способів, якими клас може повідомити VB .NET
про своє бажання отримувати події від іншого класу. Простий спосіб дуже схожий
на той, який використовувався в Vb6: на рівні модуля (або класу) оголошується змінна
класу-приймача з ключовим словом Withevents. Наприклад, якщо включити в
клас наступний рядок, що не входить ні в один з членів: Private Withevents
anemployee As Employee об'єкти цього класу
стають потенційними приймачами подій, що ініціюються класом Employee.
Звернете особливу увагу на деякі особливості цього оголошення:
Після включення цього рядка
в програму об'єктна змінна anempl oyee може використовуватися усюди, де
вас цікавить подія Salarysecurityevent. Як показано на мал. 6.2, IDE
автоматично створює обробник події з ім'ям, побудованим по схемі А_в, для
кожної об'єктної змінної, оголошеної з ключовим словом Wi thevents. Щоб викликати
«скелет» події, що автоматично згенерував, досить вибрати
його в списку, що розкривається, як на мал. 6.2.
А зараз
давайте об'єднаємо все сказане на практичному прикладі. Створіть консольне
застосування і включите наступний фрагмент в перший (стартовий) модуль: Module
Modulel Private
Withevents anemployee As Employeewithevents Sub Main() Dim tom As New Employeewithevents("Tom". 100000) anemployee = tom Console.WriteLine(tom.TheName & "has salary " & tom.Salary) anemployee.RaiseSalary(0.2d) ' Суфікс D - ознака типу Decimal Console.WriteLinettom.TheName & "still has salary " & tom.Salary) Console.WritelineC'Please press the Enter key") Console.ReadLine()
End Sub End Module
Мал.
6.2. Код обробника
події, що автоматично згенерував Тепер виберіть в
списку, що розкривається, метод anemployee_salarysecurityevent. Початковий текст
цього методу приведений нижче (для зручності читання він розбитий на декілька рядків,
а ключова секція Handles виділена жирним шрифтом): Public Sub anemployee_salarysecur1tyevent(Byval
Sender As Event_handling_i.EmployeeWithEvents, Byvaleas System.EventArgs) Handles anemployee.SalarySecurityEverrt End
Sub End
Module Звернете
увагу на символ підкреслення, доданий VB .NET між ім'ям змінної
з ключовим словом Withevents (anemployee) і ім'ям події (Salarysecurityevent),
— з ним обробник зовні майже не відрізняється від процедур подій в Vb6. Також звернете
увагу на ідентифікацію об'єкту Sender повним ім'ям (у форматі пространство_імен.
імя_класса). Наявність додаткових символів підкреслення в просторі імен
пояснюється тим, що пропуски в них не дозволені, тому VB .NET автоматично
перетворить ім'я вирішення «Event Handling 1» в «Event_handling_l»
(мал. 6.3). Нарешті, ключове слово Handles повідомляє виконавче середовище, яка
подія обробляється цією процедурою.
Мал.
6.3. Вікно
властивостей вирішення з обробкою подій Щоб приклад
став більш інтересним, замість простого виводу в консольне вікно 'ми включимо
в процедуру події команду виклику діалогового вікна: Public Sub anemployee_salarysecurityevent(Byval
Sender As Event_handling_i.EmployeeWithEvents.
Byval e As System.EventArgs) Handles anemployee.SalarySecurityEvent Msgbox(Sender.TheName
&"had an improper salary raise attempted!") End Sub Від приймача
подій ми переходимо до джерела. У клас Employee з розділу 4 необхідно внести
дві зміни, виділені в наступному лістингу жирним шрифтом: Public Class Employeewithevents Private m_name As String Private m_salary As Decimal Private Const LIMIT As Decimal =0.1d Public Event Salarysecurityeventcbyval Sender As EmployeewitheventsByval e As Eventargs) Public Sub Newcbyval aname As String.
Byval cursalary As Decimal) m_name =
aname m_salary = cursalary End Sub Readonly
Property Thename() As String Get Return
m_name End Get End Property
Readonly Property Salary() As Decimal s Get Return
m_salary End Get
' ' End
Property Public Overloads Sub Raisesalary(Byval Percent As Decimal) If Percent >
Limit'then 'Операція заборонена - необхідний пароль Raiseevent Salarysecurityeventtme, New System.EventArgs()) Else m_sa1ary = (1 + Percent) * m_salary End If End Sub Public Overloads
Sub Raisesalary(Byval Percent As Decimal. Byval Password As String) If
Password = "special" Then m_salary = (1 + Percent) * m_salary End If End Sub End Class Перший виділений
фрагмент оголошує подія, а другою ініціює його при спробі неприпустимого
підвищення зарплати. Зразковий
результат запуску програми показаний на мал. 6.4. При натисненні кнопки ОК вікно
повідомлення зникає, і в консольному вікні виводиться рядок, з якого видно,
що зарплата Тома не змінилася.
Мал.
6.4. Вікно
повідомлення, що викликається при обробці події
|
|
|||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||