Události (F#)
Události můžete přidružit uživatelské akce volání funkce a jsou důležité při programování grafického uživatelského rozhraní.Události můžete také spouštět aplikace nebo operační systém.
Zpracování událostí
Při použití grafického uživatelského rozhraní knihovny jako model Windows Forms nebo Windows Presentation Foundation (WPF) knihovnou velká část kódu aplikace spuštěna v reakci na události, které jsou předdefinované.Tyto předdefinované události jsou členy třídy grafického uživatelského rozhraní, jako jsou formuláře a ovládací prvky.Můžete přidat vlastní chování k této události, jako například klepněte na tlačítko odkazem na konkrétní pojmenované události zájmu (například Click události Form třídy) a vyvolání Add způsob, jak je znázorněno v následujícím kódu.Je-li spustit tento z F# interaktivní vynechat volání Run.
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)
Typ Add metoda je ('a -> unit) -> unit.Proto metody zpracování události přijímá jeden parametr, obvykle argumenty událostí a vrátí unit.Předchozí příklad ukazuje jako lambda výraz obslužnou rutinu události.Obslužnou rutinu události lze také hodnota funkce, jako v následujícím příkladu kódu.Následující příklad kódu také znázorňuje použití události rutiny parametry, které poskytují informace specifické pro daný typ události.Pro MouseMove předává události, systém MouseEventArgs objekt, který obsahuje X a Y polohy ukazatele.
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)
Vytvoření vlastní události
F# událostí jsou představovány F# událost třídy, která implementuje IEvent rozhraní.IEventsamotný je rozhraní, které kombinuje funkce dvě rozhraní IObservable<T> a IDelegateEvent.Proto Events mají ekvivalentní funkce Delegáti v jiných jazycích, plus další funkce z IObservable, což znamená, že události F# podporují filtrování událostí a prvotřídní funkce F# a lambda výrazy jako obslužné rutiny událostí.Tato funkce je k dispozici v modulu události.
Vytvořit událost na třídu, která pracuje stejně jako všechny ostatní.NET Framework události, přidat do třídy let vazba, která definuje Event jako pole ve třídě.Zadat argument typ požadované události jako argument typ nebo ponechejte prázdné a mít kompilátor odvození odpovídající typu.Také je nutné definovat události člen, který zpřístupňuje událost jako událost CLI.Tento člen by měl mít CLIEvent atributu.Je deklarována jako vlastnost a jeho provedení je pouze volání publikovat vlastnost události.Slouží uživatelům vaší třídy Add metoda publikované přidejte obslužnou rutinu události.Argument pro Add metoda může být lambda výraz.Můžete použít Trigger vlastnost zvýšit události, a to předáním argumentů funkce manipulačního programu události.Následující příklad kódu ukazuje to.Argument inferred typu události v tomto příkladu je n-tice, což představuje argumenty lambda výraz.
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
Výstup je takto.
Event1 occurred! Object data: Hello World!
Další funkce poskytnuté Event modul je znázorněno zde.Následující příklad kódu ukazuje základní použití Event.create Chcete-li vytvořit událost a aktivační metodu, přidat dvě obslužné rutiny událostí ve formě lambda výrazů a spustit oba výrazy lambda události.
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.")
Výstup předchozího kódu je následující.
Event occurred.
Given a value: Event occurred.
Zpracování událostí proudy
Namísto pouze pomocí přidání obslužné rutiny události pro událost Event.add funkce, můžete použít funkce Event modul proces proudy událostí vysoce přizpůsobená způsoby.To provedete pomocí kanálu vpřed (|>) společně s událostí jako první hodnota v řadě volání funkce a Event modul funguje jako další funkce volání.
Následující příklad kódu ukazuje, jak nastavit událost, pro kterou obslužná rutina pouze za určitých podmínek.
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) )
Pozorovatelné modul obsahuje podobné funkce, které pracují pozorovatelné objekty.Pozorovatelné objekty jsou podobné události, ale pouze aktivně odběru událostí, pokud samy odebírané k.
Implementace rozhraní události
Při vývoji komponent uživatelského rozhraní, často začněte vytvořením nového formuláře nebo nový ovládací prvek, který dědí z existujícího formuláře nebo ovládacího prvku.Události jsou často definovány na rozhraní a v takovém případě musí implementovat rozhraní implementovat událost.INotifyPropertyChanged Rozhraní definuje jeden PropertyChanged událostí.Následující kód ilustruje, jak implementovat událost, která je definována zděděné rozhraní:
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)
Pokud chcete zapojit události v konstruktoru, kód je o něco složitější, protože přípojku událostí musí být v then blokovat v další konstruktoru, jako v následujícím příkladu:
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)
Viz také
Referenční dokumentace
Lambda výrazy: Fun klíčové slovo (F#)
Control.Event, <'T> Třídy (F#)
Control.Event < "delegáta," Args > Třídy (F#)