F # - Sự kiện
Sự kiện cho phép các lớp gửi và nhận tin nhắn giữa các lớp khác.
Trong GUI, các sự kiện là các hành động của người dùng như nhấn phím, nhấp chuột, di chuyển chuột, v.v. hoặc một số sự kiện như thông báo do hệ thống tạo. Các ứng dụng cần phản hồi các sự kiện khi chúng xảy ra. Ví dụ, ngắt. Sự kiện được sử dụng để giao tiếp giữa các quá trình.
Các đối tượng giao tiếp với nhau thông qua truyền thông điệp đồng bộ.
Sự kiện được đính kèm với các chức năng khác; đối tượng đăng kýcallback các hàm đối với một sự kiện và các lệnh gọi lại này được thực thi khi (và nếu) sự kiện được kích hoạt bởi một số đối tượng.
Lớp Sự kiện và Mô-đun Sự kiện
Lớp Control.Event <'T> giúp tạo một đối tượng hoặc sự kiện có thể quan sát được.
Nó có các thành viên phiên bản sau để làm việc với các sự kiện:
Thành viên | Sự miêu tả |
---|---|
Công bố | Xuất bản một quan sát dưới dạng giá trị hạng nhất. |
Kích hoạt | Kích hoạt một quan sát bằng cách sử dụng các tham số đã cho. |
Mô-đun Control.Event cung cấp các chức năng để quản lý các luồng sự kiện -
Giá trị | Sự miêu tả |
---|---|
thêm: ('T → đơn vị) → Sự kiện <' Del, 'T> → đơn vị | Chạy chức năng đã cho mỗi khi sự kiện nhất định được kích hoạt. |
chọn: ('T →' U option) → IEvent <'Del,' T> → IEvent <'U> | Trả về một sự kiện mới kích hoạt trên một lựa chọn các thông báo từ sự kiện ban đầu. Chức năng lựa chọn sẽ đưa một tin nhắn gốc sang một tin nhắn mới tùy chọn. |
bộ lọc: ('T → bool) → IEvent <' Del, 'T> → IEvent <' T> | Trả về một sự kiện mới lắng nghe sự kiện ban đầu và chỉ kích hoạt sự kiện kết quả khi đối số của sự kiện chuyển qua hàm đã cho. |
map: ('T →' U) → IEvent <'Del,' T> → IEvent <'U> | Trả về một sự kiện mới chuyển các giá trị được biến đổi bởi hàm đã cho. |
hợp nhất: IEvent <'Del1,' T> → IEvent <'Del2,' T> → IEvent <'T> | Kích hoạt sự kiện đầu ra khi một trong hai sự kiện đầu vào kích hoạt. |
theo cặp: IEvent <'Del,' T> → IEvent <'T *' T> | Trả về một sự kiện mới kích hoạt vào lần kích hoạt thứ hai và tiếp theo của sự kiện đầu vào. CácNth việc kích hoạt sự kiện đầu vào sẽ chuyển các đối số từ N-1th và Nthkích hoạt như một cặp. Đối số được chuyển choN-1th kích hoạt được giữ ở trạng thái ẩn bên trong cho đến khi Nth kích hoạt xảy ra. |
phân vùng: ('T → bool) → IEvent <' Del, 'T> → IEvent <' T> * IEvent <'T> | Trả về một sự kiện mới lắng nghe sự kiện ban đầu và kích hoạt sự kiện kết quả đầu tiên nếu ứng dụng của vị từ cho các đối số sự kiện trả về true và sự kiện thứ hai nếu nó trả về false. |
quét: ('U →' T → 'U) →' U → IEvent <'Del,' T> → IEvent <'U> | Trả về một sự kiện mới bao gồm kết quả của việc áp dụng hàm tích lũy đã cho cho các giá trị liên tiếp được kích hoạt trên sự kiện đầu vào. Một mục của trạng thái bên trong ghi lại giá trị hiện tại của tham số trạng thái. Trạng thái bên trong không bị khóa trong khi thực hiện chức năng tích lũy, vì vậy cần chú ý để IEvent đầu vào không được kích hoạt bởi nhiều luồng đồng thời. |
split: ('T → Choice <' U1, 'U2>) → IEvent <' Del, 'T> → IEvent <' U1> * IEvent <'U2> | Trả về một sự kiện mới lắng nghe sự kiện ban đầu và kích hoạt sự kiện kết quả đầu tiên nếu ứng dụng của hàm cho các đối số sự kiện trả về Choice1Of2 và sự kiện thứ hai nếu nó trả về Choice2Of2. |
Tạo sự kiện
Các sự kiện được tạo và sử dụng thông qua Eventlớp học. Hàm tạo sự kiện được sử dụng để tạo sự kiện.
Thí dụ
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
Sau đó, bạn cần hiển thị trường nameChanged dưới dạng thành viên công khai, để người nghe có thể theo dõi sự kiện mà bạn sử dụng Publish tài sản của sự kiện -
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 *)
Tiếp theo, bạn thêm lệnh gọi lại vào trình xử lý sự kiện. Mỗi trình xử lý sự kiện có kiểu IEvent <'T>, cung cấp một số phương thức:
phương pháp | Sự miêu tả |
---|---|
val Thêm: sự kiện :( 'T → đơn vị) → đơn vị | Kết nối chức năng người nghe với sự kiện. Người nghe sẽ được gọi khi sự kiện được kích hoạt. |
val AddHandler: 'del → đơn vị | Kết nối một đối tượng ủy quyền của trình xử lý với sự kiện. Trình xử lý có thể được xóa sau đó bằng cách sử dụng RemoveHandler. Người nghe sẽ được gọi khi sự kiện được kích hoạt. |
val RemoveHandler: 'del → unit | Xóa đại biểu người nghe khỏi kho lưu trữ trình nghe sự kiện. |
Phần sau đây cung cấp một ví dụ đầy đủ.
Thí dụ
Ví dụ sau minh họa khái niệm và kỹ thuật được thảo luận ở trên:
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"
Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:
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!