当前位置: 首页 > 文档资料 > F# 中文教程 >

Events

优质
小牛编辑
130浏览
2023-12-01

事件允许类在彼此之间发送和接收消息。

在GUI中,事件是用户操作,如按键,单击,鼠标移动等,或者某些事件,如系统生成的通知。 应用程序需要在事件发生时对其进行响应。 例如,中断。 事件用于进程间通信。

对象通过同步消息传递相互通信。

事件附加到其他功能; 对象将callback函数注册到事件,并且当某个对象触发事件(以及如果)时,将执行这些回调。

事件类和事件模块

Control.Event 类有助于创建可观察对象或事件。

它有以下实例成员来处理事件 -

会员描述
Publish将观察结果作为第一类值发布。
Trigger使用给定参数触发观察。

Control.Event模块提供管理事件流的功能 -

描述
添加:('T→单位)→事件→单位每次触发给定事件时运行给定的函数。
选择:('T→'U选项)→IEvent →IEvent返回一个新事件,该事件触发原始事件中的一系列消息。 选择功能将原始消息带到可选的新消息。
filter:('T→bool)→IEvent →IEvent返回一个侦听原始事件的新事件,并仅在事件的参数传递给定函数时触发结果事件。
map:('T→'U)→IEvent →IEvent返回传递给定函数转换的值的新事件。
合并:IEvent →IEvent →IEvent触发任一输入事件时触发输出事件。
pairwise:IEvent →IEvent返回在第二次和随后触发输入事件时触发的新事件。 输入事件的Nth触发将来自第N-1thNth触发的参数作为一对传递。 传递给第N-1th触发的参数保持在隐藏的内部状态,直到第Nth触发发生。
分区:('T→bool)→IEvent →IEvent * IEvent返回一个侦听原始事件的新事件,如果事件参数的谓词应用程序返回true,则返回第一个结果事件,如果返回false,则返回第二个事件。
扫描:('U→'T→'U)→'U→IEvent →IEvent返回一个新事件,该事件由将给定累积函数应用于在输入事件上触发的连续值的结果组成。 内部状态项记录状态参数的当前值。 在执行累加功能期间内部状态未锁定,因此应注意输入IEvent不是由多个线程同时触发的。
拆分:('T→选择)→IEvent →IEvent * IEvent返回一个新事件,该事件侦听原始事件,如果函数应用程序返回Choice1Of2,则返回第一个结果事件;如果返回Choice2Of2,则返回第二个事件。

创建事件

通过Event类创建和使用Event 。 Event构造函数用于创建事件。

例子 (Example)

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 类型,它提供了几种方法 -

方法描述
val添加:事件:('T→单位)→单位将侦听器功能连接到事件。 触发事件时将调用侦听器。
val AddHandler:'del→unit将处理程序委托对象连接到事件。 稍后可以使用RemoveHandler删除处理程序。 触发事件时将调用侦听器。
val RemoveHandler:'del→unit从事件侦听器存储中删除侦听器委托。

以下部分提供了一个完整的示例。

例子 (Example)

以下示例演示了上面讨论的概念和技术 -

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!