События (Visual Basic)

Хотя вы можете визуализировать проект Visual Studio как ряд процедур, которые выполняются последовательно, в действительности большинство программ управляются событиями. Это означает, что поток выполнения определяется внешними вхождениями, называемыми событиями.

Событие — это сигнал, который сообщает приложению, что произошло нечто важное. Например, когда пользователь щелкает элемент управления на форме, эта форма инициирует событие Click и вызывает процедуру обработки события. События позволяют отдельным задачам взаимодействовать друг с другом. Давайте представим, что приложение выполняет задачу по сортировке в отдельном процессе. Если пользователь отменит эту сортировку, приложение отправит событие отмены, по которому процесс сортировки завершит свою работу.

Термины и основные понятия для событий

В этом разделе описываются термины и понятия, используемые с событиями в Visual Basic.

Объявление событий

События объявляются внутри классов, структур, модулей и интерфейсов с помощью ключевого слова Event, как показано в следующем примере:

Event AnEvent(ByVal EventNumber As Integer)

Вызов событий

Событие действует как сообщение о том, что произошло нечто важное. Рассылка такого сообщения называется созданием события. В Visual Basic вы создаете события с помощью инструкцииRaiseEvent, как показано в следующем примере:

RaiseEvent AnEvent(EventNumber)

События должны создаваться в пределах области действия класса, модуля или структуры, в которых они объявлены. Например, производный класс не может создавать события, унаследованные от базового класса.

Отправители событий

Любой объект, способный создать событие, считается отправителем события или источником события. Например, отправителями событий могут являться формы, элементы управления и пользовательские объекты.

Обработчики событий

Обработчики событий — это процедуры, вызываемые при создании определенного события. В качестве обработчика событий можно использовать любую допустимую подпрограмму с подходящей сигнатурой. Но в качестве обработчика событий нельзя использовать функцию, поскольку она не может возвращать значение источнику события.

Visual Basic использует стандартное соглашение об именовании для обработчиков событий, объединяющее имя отправителя события, символ подчеркивания и имя события. Например, событие Click для кнопки с именем button1 будет называться Sub button1_Click.

Примечание

Мы рекомендуем придерживаться этого соглашения об именовании при создании обработчиков событий и для пользовательских событий. Но это не обязательное условие, вы можете использовать любое допустимое имя процедуры.

Связывание событий с обработчиками событий

Чтобы обработчик событий мог выполнять свою функцию, его следует связать с соответствующим событием с помощью инструкции Handles или AddHandler.

Оператор WithEvents и предложение Handles

Инструкция WithEvents и предложение Handles предоставляют декларативный способ указания обработчиков событий. Если объект объявлен с ключевым словом WithEvents, созданные им события могут обрабатываться любой процедурой с инструкцией Handles для этого события, как показано в следующем примере:

' Declare a WithEvents variable.
Dim WithEvents EClass As New EventClass

' Call the method that raises the object's events.
Sub TestEvents()
    EClass.RaiseEvents()
End Sub

' Declare an event handler that handles multiple events.
Sub EClass_EventHandler() Handles EClass.XEvent, EClass.YEvent
    MsgBox("Received Event.")
End Sub

Class EventClass
    Public Event XEvent()
    Public Event YEvent()
    ' RaiseEvents raises both events.
    Sub RaiseEvents()
        RaiseEvent XEvent()
        RaiseEvent YEvent()
    End Sub
End Class

Инструкция WithEvents и предложение Handles часто являются наилучшим решением для обработки событий, так как декларативный синтаксис позволяет легко создавать, читать и отлаживать код программы. Но использование переменных WithEvents имеет ряд ограничений.

  • Нельзя использовать переменную WithEvents в качестве переменной объекта. То есть вы не можете объявить ее как Object. При объявлении переменной необходимо указать имя класса.

  • Так как общие события не привязаны к экземплярам класса, нельзя использовать для WithEvents декларативной обработки общих событий. Аналогично, нельзя использовать WithEvents или Handles для обработки событий от Structure. В обоих случаях для обработки таких событий можно использовать инструкцию AddHandler.

  • Вы не можете создавать массивы переменных типа WithEvents.

Переменные WithEvents позволяют одному обработчику событий обрабатывать один или несколько видов событий. Также можно создать несколько обработчиков для одного вида событий.

Предложение Handles является стандартным способом связывания события с обработчиком событий, но оно ограничено тем, что может связывать события с обработчиками событий только во время компиляции.

В некоторых случаях, например с событиями, связанными с формами или элементами управления, Visual Basic автоматически заглушает пустой обработчик событий и связывает его с событием. Например, при двойном щелчке кнопки команды в форме в режиме конструктора Visual Basic создает пустой обработчик событий и WithEvents переменную для кнопки команды, как показано в следующем коде:

Friend WithEvents Button1 As System.Windows.Forms.Button
Protected Sub Button1_Click() Handles Button1.Click
End Sub

AddHandler и RemoveHandler

Инструкция AddHandler похожа на предложение Handles, поскольку тоже позволяет задавать обработчик событий. Но AddHandler в сочетании с RemoveHandler обеспечивает большую гибкость, чем предложение Handles. Она позволяет динамически добавлять, удалять и изменять обработчики событий, связанные с событием. Если вы хотите обрабатывать общие события или события от структуры, необходимо использовать AddHandler.

AddHandler принимает два аргумента: имя события, которое предоставляет отправитель события, например элемент управления, и выражение, определяющее делегат. Класс делегата при использовании AddHandler не обязательно указывать явно, поскольку инструкция AddressOf всегда возвращает ссылку на делегат. Следующий пример связывает обработчик событий с событием, создаваемым объектом:

AddHandler Obj.XEvent, AddressOf Me.XEventHandler

Инструкция RemoveHandler, которая отсоединяет событие от обработчика событий, использует такой же синтаксис, как AddHandler. Например:

RemoveHandler Obj.XEvent, AddressOf Me.XEventHandler

В следующем примере обработчик событий связывается с событием, а затем создается событие. Обработчик событий перехватывает это событие и выводит сообщение.

Затем первый обработчик событий удаляется, а с этим событием связывается другой обработчик событий. Теперь событие создается снова и отображается другое сообщение.

Наконец, второй обработчик событий удаляется и событие создается в третий раз. Поскольку теперь нет обработчиков событий, связанных с этим событием, никакие действия не выполняются.

Module Module1

    Sub Main()
        Dim c1 As New Class1
        ' Associate an event handler with an event.
        AddHandler c1.AnEvent, AddressOf EventHandler1
        ' Call a method to raise the event.
        c1.CauseTheEvent()
        ' Stop handling the event.
        RemoveHandler c1.AnEvent, AddressOf EventHandler1
        ' Now associate a different event handler with the event.
        AddHandler c1.AnEvent, AddressOf EventHandler2
        ' Call a method to raise the event.
        c1.CauseTheEvent()
        ' Stop handling the event.
        RemoveHandler c1.AnEvent, AddressOf EventHandler2
        ' This event will not be handled.
        c1.CauseTheEvent()
    End Sub

    Sub EventHandler1()
        ' Handle the event.
        MsgBox("EventHandler1 caught event.")
    End Sub

    Sub EventHandler2()
        ' Handle the event.
        MsgBox("EventHandler2 caught event.")
    End Sub

    Public Class Class1
        ' Declare an event.
        Public Event AnEvent()
        Sub CauseTheEvent()
            ' Raise an event.
            RaiseEvent AnEvent()
        End Sub
    End Class

End Module

Обработка событий, наследуемых от базового класса

Производные классы, которые наследуют характеристики из базового класса, могут обрабатывать события, создаваемые этим базовым классом, используя инструкцию Handles MyBase.

Обработка событий из базового класса

  • Объявите обработчик событий в производном классе, добавив инструкцию Handles MyBase.eventname в строку объявления процедуры обработчика событий, где eventname — это имя события в базовом классе, которое вы хотите обрабатывать. Например:

    Public Class BaseClass
        Public Event BaseEvent(ByVal i As Integer)
        ' Place methods and properties here.
    End Class
    
    Public Class DerivedClass
        Inherits BaseClass
        Sub EventHandler(ByVal x As Integer) Handles MyBase.BaseEvent
            ' Place code to handle events from BaseClass here.
        End Sub
    End Class
    
Заголовок Описание
Пошаговое руководство. Объявление и вызов событий Предоставляет пошаговую инструкцию для объявления и создания событий класса.
Пошаговое руководство. Обработка событий Описывает способ создания процедуры обработчика событий.
Практическое руководство. Объявление пользовательских событий для предотвращения блокировки Показывает, как определить пользовательское событие, которое позволяет асинхронно вызывать обработчики событий.
Практическое руководство. Объявление пользовательских событий для экономии памяти Показывает, как определить пользовательское событие, которое использует память только при обработке события.
Устранение неполадок, связанных с унаследованными обработчиками событий, в Visual Basic Перечисляет распространенные проблемы, возникающие для обработчиков событий в наследуемых компонентах.
События Обзор модели событий .NET Framework.
Создание обработчиков событий в Windows Forms Описывает, как работать с событиями, связанными с объектами Windows Forms.
Делегаты Предоставляет обзор делегатов в Visual Basic.