Partager via


Événements (F#)

Les événements vous permettent d'associer des appels de fonction à des actions utilisateur ; ils sont un élément important de la programmation d'interfaces GUI. Des événements peuvent également être déclenchés par vos applications ou par le système d'exploitation.

Gestion des événements

Lorsque vous utilisez une bibliothèque d'interfaces GUI telle que Windows Forms ou Windows Presentation Foundation (WPF), une grande partie du code dans votre application s'exécute en réponse à des événements prédéfinis par la bibliothèque. Ces événements prédéfinis sont membres de classes GUI, comme les formulaires et les contrôles. Vous pouvez ajouter un comportement personnalisé à un événement préexistant, tel qu'un clic de bouton, en référençant l'événement nommé spécifique présentant un intérêt (par exemple, l'événement Click de la classe Form) et en appelant la méthode Add, comme indiqué dans le code suivant. Si vous exécutez ceci à partir de F# Interactive, omettez d'appeler 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)

Le type de la méthode Add est ('a -> unit) -> unit. Par conséquent, la méthode du gestionnaire d'événements prend un paramètre, en général les arguments d'événement, et retourne unit. L'exemple précédent présente le gestionnaire d'événements en tant qu'expression lambda. Le gestionnaire d'événements peut également être une valeur de fonction, comme dans l'exemple de code suivant. L'exemple de code suivant illustre également l'utilisation des paramètres du gestionnaire d'événements, qui fournissent des informations spécifiques au type d'événement. Pour un événement MouseMove, le système passe un objet MouseEventArgs, qui contient les positions X et Y du pointeur.

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)

Création d'événements personnalisés

Les événements F# sont représentés par la classe Event F#, qui implémente l'interface IEvent. IEvent est une interface qui combine les fonctionnalités de deux autres interfaces, IObservable<T> et IDelegateEvent. Par conséquent, les Events ont les fonctionnalités équivalentes des délégués dans d'autres langues, plus les fonctionnalités supplémentaires d'IObservable, ce qui signifie que les événements F# prennent en charge le filtrage d'événements, ainsi que l'utilisation de fonctions de première classe F# et expressions lambda comme gestionnaires d'événements. Ces fonctionnalités sont fournies dans le module Event.

Pour créer un événement sur une classe qui agit juste comme tout autre événement .NET Framework, ajoutez à la classe une liaison let qui définit un Event comme un champ dans une classe. Vous pouvez spécifier le type d'argument d'événement souhaité comme argument de type ou le laisser vide et indiquer au compilateur de déduire le type approprié. Vous devez également définir un membre d'événement qui expose l'événement comme un événement CLI. Ce membre doit avoir l'attribut CLIEvent. Il est déclaré comme une propriété et son implémentation consiste juste en un appel à la propriété Publish de l'événement. Les utilisateurs de votre classe peuvent utiliser la méthode Add de l'événement publié pour ajouter un gestionnaire. L'argument de la méthode Add peut être une expression lambda. Vous pouvez utiliser la propriété Trigger de l'événement pour le déclencher, en passant l'argument à la fonction de gestionnaire. L'exemple de code suivant illustre ceci. Dans cet exemple, l'argument de type déduit pour l'événement est un tuple, qui représente les arguments de l'expression lambda.

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

La sortie est la suivante.

Event1 occurred! Object data: Hello World!

Les fonctionnalités supplémentaires fournies par le module Event sont illustrées ici. L'exemple de code suivant illustre l'utilisation de base d'Event.create pour créer un événement et une méthode de déclencheur, ajouter deux gestionnaires d'événements sous forme d'expressions lambda, puis déclencher l'événement pour exécuter les deux expressions 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.")

La sortie du code précédent est la suivante.

Event occurred.
Given a value: Event occurred.

Traitement de flux d'événements

Au lieu d'ajouter simplement un gestionnaire d'événements pour un événement à l'aide de la fonction Event.add, vous pouvez utiliser les fonctions du module Event pour traiter les flux d'événements de manière hautement personnalisée. Pour cela, vous utilisez le canal (|>) avec l'événement comme première valeur dans une série d'appels de fonction, et les fonctions du module Event comme appels de fonction suivants.

L'exemple de code suivant illustre comment configurer un événement pour lequel le gestionnaire est uniquement appelé sous certaines conditions.

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) )

Le module Observable contient des fonctions semblables qui opèrent sur les objets observables. Les objets observables sont semblables aux événements, mais s'abonnent activement aux événements uniquement s'ils font eux-mêmes l'objet d'un abonnement.

Voir aussi

Référence

Expressions lambda : mot clé fun (F#)

Control.Event, module (F#)

Control.Event<'T>, classe (F#)

Control.Event<'Delegate,'Args>, classe (F#)

Concepts

Membres (F#)

Événements et délégués

Historique des modifications

Date

Historique

Motif

Janvier 2011

Souligner l'utilisation d'Event plutôt que de DelegateEvent.

Améliorations apportées aux informations.