事件
事件允许类在彼此之间发送和接收消息。
在GUI中,事件是用户动作,例如按键,点击,鼠标移动等,或者像系统生成的通知的某些事件。 应用程序需要在事件发生时对其进行响应。 例如,中断。 事件用于进程间通信。
对象通过同步消息传递彼此通信。
事件附加到其他功能; 对象将回调函数注册到事件,并且这些回调在(和if)事件由某个对象触发时执行。
事件类和事件模块
Control.Event 类有助于创建可观察的对象或事件。
它有以下函数来处理事件
函数 |
描述 |
Publish |
发布观察值作为第一类值。 |
Trigger |
触发器使用给定参数的观察。 |
该Control.Event模块提供了一个管理事件流功能
值 |
描述 |
add : ('T → unit) → Event<'Del,'T> → unit |
每个触发特定事件时运行给定的功能。 |
choose : ('T → 'U option) → IEvent<'Del,'T> → IEvent<'U> |
返回时触发从原始事件选择消息的新事件。选择功能需要一个原始消息到可选的新消息。 |
filter : ('T → bool) → IEvent<'Del,'T> → IEvent<'T> |
返回监听到原始事件,只有当参数的事件传递给定的函数触发所得事件的新事件。 |
map : ('T → 'U) → IEvent<'Del, 'T> → IEvent<'U> |
返回传递给定函数转换值的新事件。 |
merge : IEvent<'Del1,'T> → IEvent<'Del2,'T> → IEvent<'T> |
触发输出事件时,无论是输入事件火。 |
pairwise : IEvent<'Del,'T> → IEvent<'T * 'T> |
返回触发输入事件第二次和后续触发的新事件。 输入事件的第N次触发将来自第N-1和第N次触发的自变量作为一对传递。 传递到第N-1次触发的参数保持在隐藏内部状态,直到发生第N次触发。 |
partition : ('T → bool) → IEvent<'Del,'T> → IEvent<'T> * IEvent<'T> |
返回监听到原始事件并触发所述第一结果的事件,如果谓词事件参数的应用程序返回真一个新的事件,和第二事件,如果它返回false。 |
scan : ('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类使用。事件构造函数用于创建一个事件。
例
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地址:事件:('T→单位)→单元 |
连接侦听器函数事件。当事件被触发的监听器会被调用。 |
VAL的AddHandler:“德尔→单元 |
连接处理程序委托对象的事件。处理程序可使用RemoveHandler在稍后删除。当事件被触发的监听器会被调用。 |
VAL RemoveHandler:“德尔→单元 |
移除事件侦听器店监听器委派。 |
以下部分提供了一个完整的例子。
例
下面的示例演示的概念和技术上面讨论
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"
当你编译和执行程序,它产生以下输出
Worker changed name! New name: William
Worker changed name! New name: Bill
-- Another handler attached to NameChanged!
Worker changed shift! New shift: Morning
Worker changed shift! New shift: Night
-- Another handler attached to ShiftChanged!