Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Peristiwa memungkinkan Anda mengaitkan panggilan fungsi dengan tindakan pengguna dan penting dalam pemrograman GUI. Peristiwa juga dapat dipicu oleh aplikasi Anda atau oleh sistem operasi.
Menangani Peristiwa
Saat Anda menggunakan pustaka GUI seperti Windows Forms atau Windows Presentation Foundation (WPF), banyak kode dalam aplikasi Anda berjalan sebagai respons terhadap peristiwa yang telah ditentukan sebelumnya oleh pustaka. Peristiwa yang telah ditentukan sebelumnya ini adalah anggota kelas GUI seperti formulir dan kontrol. Anda dapat menambahkan perilaku kustom ke peristiwa yang sudah ada sebelumnya, seperti klik tombol, dengan merujuk peristiwa minat bernama tertentu (misalnya, Click peristiwa Form kelas) dan memanggil Add metode, seperti yang ditunjukkan dalam kode berikut. Jika Anda menjalankan ini dari F# Interactive, hilangkan panggilan ke System.Windows.Forms.Application.Run(System.Windows.Forms.Form).
open System.Windows.Forms
let form = new Form(Text="F# Windows Form",
Visible = true,
TopMost = true)
form.Click.Add(fun evArgs -> System.Console.Beep())
Application.Run(form)
Jenis Add metodenya adalah ('a -> unit) -> unit. Oleh karena itu, metode penanganan aktivitas mengambil satu parameter, biasanya argumen peristiwa, dan mengembalikan unit. Contoh sebelumnya memperlihatkan penanganan aktivitas sebagai ekspresi lambda. Penanganan aktivitas juga dapat menjadi nilai fungsi, seperti dalam contoh kode berikut. Contoh kode berikut juga menunjukkan penggunaan parameter penanganan aktivitas, yang memberikan informasi khusus untuk jenis peristiwa.
MouseMove Untuk peristiwa, sistem meneruskan System.Windows.Forms.MouseEventArgs objek, yang berisi X posisi dan Y penunjuk.
open System.Windows.Forms
let Beep evArgs =
System.Console.Beep( )
let form = new Form(Text = "F# Windows Form",
Visible = true,
TopMost = true)
let MouseMoveEventHandler (evArgs : System.Windows.Forms.MouseEventArgs) =
form.Text <- System.String.Format("{0},{1}", evArgs.X, evArgs.Y)
form.Click.Add(Beep)
form.MouseMove.Add(MouseMoveEventHandler)
Application.Run(form)
Membuat Kejadian Kustom
Peristiwa F# diwakili oleh jenis Peristiwa F#, yang mengimplementasikan antarmuka IEvent .
IEvent adalah antarmuka yang menggabungkan fungsionalitas dua antarmuka lain, System.IObservable<'T> dan IDelegateEvent. Oleh karena itu, Eventmemiliki fungsionalitas delegasi yang setara dalam bahasa lain, ditambah fungsionalitas tambahan dari IObservable, yang berarti bahwa peristiwa F# mendukung pemfilteran peristiwa dan menggunakan fungsi kelas satu F# dan ekspresi lambda sebagai penanganan aktivitas. Fungsionalitas ini disediakan dalam modul Peristiwa.
Untuk membuat peristiwa di kelas yang bertindak sama seperti peristiwa .NET Framework lainnya, tambahkan ke kelas pengikatan let yang mendefinisikan Event sebagai bidang di kelas. Anda dapat menentukan jenis argumen peristiwa yang diinginkan sebagai argumen jenis, atau membiarkannya kosong dan membuat pengkompilasi menyimpulkan jenis yang sesuai. Anda juga harus menentukan anggota peristiwa yang mengekspos peristiwa sebagai peristiwa CLI. Anggota ini harus memiliki atribut CLIEvent . Ini dinyatakan seperti properti dan implementasinya hanya panggilan ke properti Terbitkan peristiwa. Pengguna kelas Anda dapat menggunakan Add metode peristiwa yang diterbitkan untuk menambahkan handler. Argumen untuk Add metode dapat berupa ekspresi lambda. Anda dapat menggunakan Trigger properti peristiwa untuk menaikkan peristiwa, meneruskan argumen ke fungsi handler. Contoh kode berikut mengilustrasikan hal ini. Dalam contoh ini, argumen jenis yang disimpulkan untuk peristiwa adalah tuple, yang mewakili argumen untuk ekspresi lambda.
open System.Collections.Generic
type MyClassWithCLIEvent() =
let event1 = new Event<string>()
[<CLIEvent>]
member this.Event1 = event1.Publish
member this.TestEvent(arg) =
event1.Trigger(arg)
let classWithEvent = new MyClassWithCLIEvent()
classWithEvent.Event1.Add(fun arg ->
printfn "Event1 occurred! Object data: %s" arg)
classWithEvent.TestEvent("Hello World!")
System.Console.ReadLine() |> ignore
Outputnya sebagai berikut.
Event1 occurred! Object data: Hello World!
Fungsionalitas tambahan yang disediakan oleh Event modul diilustrasikan di sini. Contoh kode berikut mengilustrasikan penggunaan Event.create dasar untuk membuat peristiwa dan metode pemicu, menambahkan dua penanganan aktivitas dalam bentuk ekspresi lambda, lalu memicu peristiwa untuk menjalankan kedua ekspresi lambda.
type MyType() =
let myEvent = new Event<_>()
member this.AddHandlers() =
Event.add (fun string1 -> printfn "%s" string1) myEvent.Publish
Event.add (fun string1 -> printfn "Given a value: %s" string1) myEvent.Publish
member this.Trigger(message) =
myEvent.Trigger(message)
let myMyType = MyType()
myMyType.AddHandlers()
myMyType.Trigger("Event occurred.")
Output kode sebelumnya adalah sebagai berikut.
Event occurred.
Given a value: Event occurred.
Memproses Aliran Peristiwa
Alih-alih hanya menambahkan penanganan aktivitas untuk peristiwa dengan menggunakan fungsi Event.add , Anda dapat menggunakan fungsi dalam Event modul untuk memproses aliran peristiwa dengan cara yang sangat disesuaikan. Untuk melakukan ini, Anda menggunakan pipa penerusan (|>) bersama dengan peristiwa sebagai nilai pertama dalam serangkaian panggilan fungsi, dan Event fungsi modul sebagai panggilan fungsi berikutnya.
Contoh kode berikut menunjukkan cara menyiapkan peristiwa di mana handler hanya dipanggil dalam kondisi tertentu.
let form = new Form(Text = "F# Windows Form",
Visible = true,
TopMost = true)
form.MouseMove
|> Event.filter ( fun evArgs -> evArgs.X > 100 && evArgs.Y > 100)
|> Event.add ( fun evArgs ->
form.BackColor <- System.Drawing.Color.FromArgb(
evArgs.X, evArgs.Y, evArgs.X ^^^ evArgs.Y) )
Modul Yang Dapat Diamati berisi fungsi serupa yang beroperasi pada objek yang dapat diamati. Objek yang dapat diamati mirip dengan peristiwa tetapi hanya secara aktif berlangganan peristiwa jika mereka sendiri sedang berlangganan.
Menerapkan Peristiwa Antarmuka
Saat Anda mengembangkan komponen UI, Anda sering memulai dengan membuat formulir baru atau kontrol baru yang mewarisi dari formulir atau kontrol yang ada. Peristiwa sering didefinisikan pada antarmuka, dan, dalam hal ini, Anda harus mengimplementasikan antarmuka untuk mengimplementasikan peristiwa. Antarmuka System.ComponentModel.INotifyPropertyChanged mendefinisikan satu System.ComponentModel.INotifyPropertyChanged.PropertyChanged peristiwa. Kode berikut mengilustrasikan cara mengimplementasikan peristiwa yang ditentukan antarmuka yang diwariskan ini:
module CustomForm
open System.Windows.Forms
open System.ComponentModel
type AppForm() as this =
inherit Form()
// Define the propertyChanged event.
let propertyChanged = Event<PropertyChangedEventHandler, PropertyChangedEventArgs>()
let mutable underlyingValue = "text0"
// Set up a click event to change the properties.
do
this.Click |> Event.add(fun evArgs ->
this.Property1 <- "text2"
this.Property2 <- "text3")
// This property does not have the property-changed event set.
member val Property1 : string = "text" with get, set
// This property has the property-changed event set.
member this.Property2
with get() = underlyingValue
and set(newValue) =
underlyingValue <- newValue
propertyChanged.Trigger(this, new PropertyChangedEventArgs("Property2"))
// Expose the PropertyChanged event as a first class .NET event.
[<CLIEvent>]
member this.PropertyChanged = propertyChanged.Publish
// Define the add and remove methods to implement this interface.
interface INotifyPropertyChanged with
member this.add_PropertyChanged(handler) = propertyChanged.Publish.AddHandler(handler)
member this.remove_PropertyChanged(handler) = propertyChanged.Publish.RemoveHandler(handler)
// This is the event-handler method.
member this.OnPropertyChanged(args : PropertyChangedEventArgs) =
let newProperty = this.GetType().GetProperty(args.PropertyName)
let newValue = newProperty.GetValue(this :> obj) :?> string
printfn "Property {args.PropertyName} changed its value to {newValue}"
// Create a form, hook up the event handler, and start the application.
let appForm = new AppForm()
let inpc = appForm :> INotifyPropertyChanged
inpc.PropertyChanged.Add(appForm.OnPropertyChanged)
Application.Run(appForm)
Jika Anda ingin menghubungkan peristiwa di konstruktor, kodenya sedikit lebih rumit karena hookup peristiwa harus berada di then blok di konstruktor tambahan, seperti dalam contoh berikut:
module CustomForm
open System.Windows.Forms
open System.ComponentModel
// Create a private constructor with a dummy argument so that the public
// constructor can have no arguments.
type AppForm private (dummy) as this =
inherit Form()
// Define the propertyChanged event.
let propertyChanged = Event<PropertyChangedEventHandler, PropertyChangedEventArgs>()
let mutable underlyingValue = "text0"
// Set up a click event to change the properties.
do
this.Click |> Event.add(fun evArgs ->
this.Property1 <- "text2"
this.Property2 <- "text3")
// This property does not have the property changed event set.
member val Property1 : string = "text" with get, set
// This property has the property changed event set.
member this.Property2
with get() = underlyingValue
and set(newValue) =
underlyingValue <- newValue
propertyChanged.Trigger(this, new PropertyChangedEventArgs("Property2"))
[<CLIEvent>]
member this.PropertyChanged = propertyChanged.Publish
// Define the add and remove methods to implement this interface.
interface INotifyPropertyChanged with
member this.add_PropertyChanged(handler) = this.PropertyChanged.AddHandler(handler)
member this.remove_PropertyChanged(handler) = this.PropertyChanged.RemoveHandler(handler)
// This is the event handler method.
member this.OnPropertyChanged(args : PropertyChangedEventArgs) =
let newProperty = this.GetType().GetProperty(args.PropertyName)
let newValue = newProperty.GetValue(this :> obj) :?> string
printfn "Property {args.PropertyName} changed its value to {newValue}"
new() as this =
new AppForm(0)
then
let inpc = this :> INotifyPropertyChanged
inpc.PropertyChanged.Add(this.OnPropertyChanged)
// Create a form, hook up the event handler, and start the application.
let appForm = new AppForm()
Application.Run(appForm)