События позволяют классам отправлять и получать сообщения между собой.
В графическом интерфейсе события — это действия пользователя, такие как нажатие клавиш, щелчки, движения мыши и т. Д., Или такие события, как системные уведомления. Приложения должны реагировать на события, когда они происходят. Например, прерывает. События используются для межпроцессного взаимодействия.
Объекты общаются друг с другом посредством синхронной передачи сообщений.
События привязаны к другим функциям; объекты регистрируют функции обратного вызова для события, и эти обратные вызовы выполняются, когда (и если) событие запускается каким-либо объектом.
Класс события и модуль события
Класс Control.Event <‘T> помогает в создании наблюдаемого объекта или события.
У него есть следующие члены экземпляра для работы с событиями —
член | Описание |
---|---|
Публиковать | Публикует наблюдение как первоклассное значение. |
Спусковой крючок | Запускает наблюдение с использованием заданных параметров. |
Модуль Control.Event предоставляет функции для управления потоками событий —
Значение | Описание |
---|---|
добавить: (‘T → единица) → Событие <‘ Del, ‘T> → единица | Запускает данную функцию каждый раз, когда происходит указанное событие. |
выберите: (опция ‘T →’ U) → IEvent <‘Del,’ T> → IEvent <‘U> | Возвращает новое событие, которое запускается при выборе сообщений из исходного события. Функция выбора переводит исходное сообщение в необязательное новое сообщение. |
фильтр: (‘T → bool) → IEvent <‘ Del, ‘T> → IEvent <‘ T> | Возвращает новое событие, которое прослушивает исходное событие и запускает результирующее событие, только когда аргумент события передает заданную функцию. |
карта: (‘T →’ U) → IEvent <‘Del,’ T> → IEvent <‘U> | Возвращает новое событие, которое передает значения, преобразованные данной функцией. |
объединить: IEvent <‘Del1,’ T> → IEvent <‘Del2,’ T> → IEvent <‘T> | Запускает выходное событие при срабатывании любого из входных событий. |
попарно: IEvent <‘Del,’ T> → IEvent <‘T *’ T> | Возвращает новое событие, которое срабатывает при втором и последующем срабатывании входного события. N-й триггер входного события передает аргументы от N-1-го и N-го триггеров в виде пары. Аргумент, переданный в N-1-й запуск, удерживается в скрытом внутреннем состоянии до тех пор, пока не произойдет N-й запуск. |
раздел: (‘T → bool) → IEvent <‘ Del, ‘T> → IEvent <‘ T> * IEvent <‘T> | Возвращает новое событие, которое прослушивает исходное событие и запускает первое результирующее событие, если применение предиката к аргументам события вернуло true, и второе событие, если оно вернуло false. |
сканирование: (‘U →’ T → ‘U) →’ U → IEvent <‘Del,’ T> → IEvent <‘U> | Возвращает новое событие, состоящее из результатов применения данной функции накопления к последовательным значениям, сработавшим во входном событии. Элемент внутреннего состояния записывает текущее значение параметра состояния. Внутреннее состояние не блокируется во время выполнения функции накопления, поэтому следует позаботиться о том, чтобы вход IEvent не запускался несколькими потоками одновременно. |
split: (‘T → Choice <‘ U1, ‘U2>) → IEvent <‘ Del, ‘T> → IEvent <‘ U1> * IEvent <‘U2> | Возвращает новое событие, которое прослушивает исходное событие и запускает первое результирующее событие, если приложение функции к аргументам события вернуло Choice1Of2, и второе событие, если оно возвращает Choice2Of2. |
Создание событий
События создаются и используются через класс Event . Конструктор Event используется для создания события.
пример
type Worker(name : string, shift : string) = let mutable _name = name; let mutable _shift = shift; let nameChanged = new Event<unit>() (* creates event *) let shiftChanged = new Event<unit>() (* creates event *) member this.Name with get() = _name and set(value) = _name <- value member this.Shift with get() = _shift and set(value) = _shift <- value
После этого вам нужно выставить поле nameChanged как открытый член, чтобы слушатели могли подключиться к событию, для которого вы используете свойство Publish события —
type Worker(name : string, shift : string) = let mutable _name = name; let mutable _shift = shift; let nameChanged = new Event<unit>() (* creates event *) let shiftChanged = new Event<unit>() (* creates event *) member this.NameChanged = nameChanged.Publish (* exposed event handler *) member this.ShiftChanged = shiftChanged.Publish (* exposed event handler *) member this.Name with get() = _name and set(value) = _name <- value nameChanged.Trigger() (* invokes event handler *) member this.Shift with get() = _shift and set(value) = _shift <- value shiftChanged.Trigger() (* invokes event handler *)
Затем вы добавляете обратные вызовы к обработчикам событий. Каждый обработчик событий имеет тип IEvent <‘T>, который предоставляет несколько методов:
метод | Описание |
---|---|
val Добавить: event 🙁 ‘T → unit) → unit | Подключает функцию слушателя к событию. Слушатель будет вызван при возникновении события. |
val AddHandler: ‘del → unit | Соединяет объект делегата обработчика с событием. Обработчик может быть позже удален с помощью RemoveHandler. Слушатель будет вызван при возникновении события. |
val RemoveHandler: ‘del → unit | Удаляет делегат слушателя из хранилища слушателей событий. |
В следующем разделе приведен полный пример.
пример
Следующий пример демонстрирует концепцию и методы, обсужденные выше —
type Worker(name : string, shift : string) = let mutable _name = name; let mutable _shift = shift; let nameChanged = new Event<unit>() (* creates event *) let shiftChanged = new Event<unit>() (* creates event *) member this.NameChanged = nameChanged.Publish (* exposed event handler *) member this.ShiftChanged = shiftChanged.Publish (* exposed event handler *) member this.Name with get() = _name and set(value) = _name <- value nameChanged.Trigger() (* invokes event handler *) member this.Shift with get() = _shift and set(value) = _shift <- value shiftChanged.Trigger() (* invokes event handler *) let wk = new Worker("Wilson", "Evening") wk.NameChanged.Add(fun () -> printfn "Worker changed name! New name: %s" wk.Name) wk.Name <- "William" wk.NameChanged.Add(fun () -> printfn "-- Another handler attached to NameChanged!") wk.Name <- "Bill" wk.ShiftChanged.Add(fun () -> printfn "Worker changed shift! New shift: %s" wk.Shift) wk.Shift <- "Morning" wk.ShiftChanged.Add(fun () -> printfn "-- Another handler attached to ShiftChanged!") wk.Shift <- "Night"
Когда вы компилируете и запускаете программу, она выдает следующий вывод: