Olaylar (F#)
Olaylar, işlev çağrılarını kullanıcı eylemleriyle ilişkilendirmenize olanak tanır ve GUI programlamada önemlidir.Olaylar, uygulamalarınız veya işletim sistemi tarafından da tetiklenebilir.
Olayları İşleme
Windows Forms veya Windows Presentation Foundation (WPF) gibi bir GUI kitaplığı kullandığınızda, uygulamanızdaki kodun çoğu kitaplık tarafından önceden tanımlanan olaylara yanıt olarak çalıştırılır.Bu önceden tanımlı olaylar, formlar ve denetimler gibi GUI sınıflarının üyeleridir.Belirli adlandırılmış olaya (örneğin, Form sınıfının Click olayı) başvurarak ve aşağıdaki kodda gösterildiği gibi Add yöntemini çağırarak, bir düğmeyi tıklamak gibi önceden varolan bir olaya özel davranış ekleyebilirsiniz.Bunu F# Interactive'den çalıştırırsanız, Run çağrısını atın.
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)
Add yönteminin türü ('a -> unit) -> unit'dir.Bu nedenle, olay işleyicisi yöntemi genellikle olay bağımsız değişkenleri olmak üzere bir parametre alır ve unit döndürür.Önceki örnekte, olay işleyici lambda ifadesi olarak gösterilmiştir.Olay işleyicisi, aşağıdaki kod örneğinde olduğu gibi, bir işlev değeri de olabilir.Aşağıdaki kod örneğinde, olay türüne özgü bilgiler sağlayan olay işleyicisi parametrelerinin kullanımı gösterilmektedir.Bir MouseMove olayı için, sistem, işaretçinin X ve Y konumunu içeren MouseEventArgs nesnesini geçirir.
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)
Özel Olaylar Oluşturma
F# olayları, IEvent arabirimini gerçekleştiren F# Event sınıfını temsil eder.IEvent, IObservable ve IDelegateEvent şeklinde iki başka arabirimin işlevselliğini birleştiren bir arabirimdir.Bu nedenle, Event'lerin diğer dillerde denk temsilci işlevsellikleri, artı ekIObservable işlevsellikleri vardır ve bu, F# olaylarının olay filtrelemeyi ve F# birinci sınıf işlevlerini ve lambda ifadelerini olay işleyiciler olarak destekledikleri anlamına gelir.Bu işlevsellik, Olay modülünde sağlanır.
Başka herhangi bir .NET Framework olayı gibi davranan bir sınıfta bir olay oluşturmak için, sınıfa bir sınıfta bir alan olarak bir Event tanımlayan bir let bağlanma ekleyin.İstenen olay bağımsız değişkeni türünü tür bağımsız değişkeni olarak belirtebilir veya boş bırakarak derleyicinin uygun türü ortaya çıkarmasını sağlayabilirsiniz.Ayrıca, olay CLI olayı olarak sunan bir olay üyesi de tanımlamanız gerekir.Bu üye, CLIEvent özniteliğine sahip olmalıdır.Bir özellik gibi bildirilir ve uygulanması, olayın Yayımla özelliğine bir çağrı gibidir.Sınıfınızın kullanıcıları, yayımlanan olayın Add yöntemini bir işleyici eklemek için kullanabilir.Add yöntemi için bağımsız değişken bir lambda ifadesi olabilir.Olayı oluşturmak için Trigger özelliğini kullanarak, bağımsız değişkenleri işleyici işlevine geçirebilirsiniz.Aşağıdaki kod örneği bunu gösterir.Bu örnekte, olay için gösterilen tür bağımsız değişkeni, lambda ifadesi için bağımsız değişkenleri temsil eden bir kayıt düzenidir.
open System.Collections.Generic
type MyClassWithCLIEvent() =
let event1 = new Event<_>()
[<CLIEvent>]
member this.Event1 = event1.Publish
member this.TestEvent(arg) =
event1.Trigger(this, arg)
let classWithEvent = new MyClassWithCLIEvent()
classWithEvent.Event1.Add(fun (sender, arg) ->
printfn "Event1 occurred! Object data: %s" arg)
classWithEvent.TestEvent("Hello World!")
System.Console.ReadLine() |> ignore
Çıktı aşağıdaki gibidir:
Event1 occurred! Object data: Hello World!
Event modülü tarafından sağlanan ek işlevsellik burada gösterilmiştir.Aşağıdaki kod örneği, bir olay oluşturmak ve bir yöntemi tetiklemek, lambda ifadeleri biçiminde iki olay işleyicisi eklemek ve sonra her iki lambda ifadesini yürütmek üzere olayı tetiklemek için temel Event.create kullanımını gösterir.
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.")
Önceki kodun çıktısı aşağıdaki gibidir.
Event occurred.
Given a value: Event occurred.
Olay Akışını İşleme
Event.add işlevini kullanarak bir olay için yalnızca bir olay işleyicisi eklemek yerine, olay akışlarını oldukça özelleştirilebilir yollarla işlemek için Event modülündeki işlevleri kullanabilirsiniz.Bunu yapmak için, bir dizi işlev çağrısında ilk değer olarak ileriye doğru kanalı (|>) ve izleyen işlev çağrıları olarak Event modülü işlevlerini olayla birlikte kullanın.
Aşağıdaki kod örneği, işleyicinin yalnızca belirli koşullarda çağrıldığı bir olayın nasıl ayarlanacağını gösterir.
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) )
Gözlemlenebilir modül, gözlemlenebilir nesneler üzerinde çalışan benzer işlevleri içerir.Gözlemlenebilir nesneler olaylara benzer, fakat yalnızca, kendilerine abone olunuyorsa olaylara etkin olarak abone olurlar.
Bir Arabirim Olayı Uygulama
UI bileşenleri geliştirirken, genellikle varolan bir formdan veya denetimden devralan yeni bir form veya yeni bir denetim oluşturarak başlarsınız.Olaylar genellikle bir arabirimde tanımlanır ve bu o durumda, olayı gerçekleştirmek için arabirimi gerçekleştirmeniz gerekir.INotifyPropertyChanged arabirimi tek bir PropertyChanged olayı gerçekleştirir.Aşağıdaki kod, bu devralınan arabirimde tanımlanan olayın nasıl uygulanacağını göstermektedir:
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 %s changed its value to %s" args.PropertyName 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)
Olayı oluşturucuya bağlamak isterseniz, aşağıdaki örnekte olduğu gibi olay bağlamanın then öbeğinde ek bir oluşturucuda yer alması gerektiğinden, kod biraz daha karmaşıktır:
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 %s changed its value to %s" args.PropertyName 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)
Ayrıca bkz.
Başvuru
Lambda İfadeleri: fun Anahtar Sözcüğü (F#)
Control.Event<'Delegate,'Args> Sınıfı (F#)