Partilhar via


Eventos (F#)

Os eventos permitem que você associe a ações do usuário de chamadas de função e são importantes na programação de GUI. Eventos também podem ser acionados por seus aplicativos ou pelo sistema operacional.

Tratamento de eventos

Quando você usa uma biblioteca de GUI, como Windows Forms ou Windows Presentation Foundation (WPF), muito do código em seu aplicativo é executado em resposta a eventos que são predefinidas pela biblioteca. Esses eventos predefinidos são membros de classes de GUI como, por exemplo, formulários e controles. Você pode adicionar o comportamento personalizado a um evento preexistente, como, por exemplo, clicar em um botão, fazendo referência a específica chamada de evento de interesse (por exemplo, o Click evento da Form classe) e invocando o Add método, conforme mostrado no código a seguir. Se você executar este procedimento de F# interativo, omitir a chamada para 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)

O tipo da Add método é ('a -> unit) -> unit. Portanto, o método de manipulador de eventos recebe um parâmetro, normalmente, os argumentos do evento e retorna unit. O exemplo anterior mostra o manipulador de eventos como uma expressão lambda. O manipulador de eventos também pode ser um valor de função, como no exemplo de código a seguir. O exemplo de código a seguir mostra também o uso do evento parâmetros do manipulador, que fornecem informações específicas para o tipo de evento. Para um MouseMove o sistema de evento, passa um MouseEventArgs objeto, que contém o X e Y a posição do ponteiro.

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)

Criando eventos personalizados

F# eventos são representados por F# evento de classe que implementa o IEvent interface. IEventé uma interface que combina a funcionalidade de duas interfaces, IObservable<T> e IDelegateEvent. Portanto, Events' possui a funcionalidade equivalente de delegados em outros idiomas, mais a funcionalidade adicional de IObservable, o que significa que F# eventos oferecem suporte a eventos de filtragem e usando funções de primeira classe F# e as expressões lambda como manipuladores de eventos. Essa funcionalidade é fornecida no módulo de eventos.

Para criar um evento em uma classe que funciona exatamente como qualquer outro.NET de evento do Framework, adicione à classe um let ligação que define um Event como um campo em uma classe. Especifique o tipo de argumento de evento desejado como o argumento de tipo, ou deixe em branco e que o compilador para inferir o tipo apropriado. Você também deve definir um membro de evento que expõe o evento como um evento CLI. Este membro deve ter o CLIEvent atributo. Ela é declarada como uma propriedade e sua implementação é apenas uma chamada para o Publicar a propriedade do evento. Os usuários de sua classe podem usar o Add o método do evento publicado para adicionar um manipulador. O argumento para o Add método pode ser uma expressão lambda. Você pode usar o Trigger a propriedade do evento para disparar o evento, passando um argumento para a função de manipulador. O exemplo de código a seguir ilustra isso. Neste exemplo, o argumento de tipo inferido para o evento é uma tupla, que representa os argumentos para a expressão 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

A saída é da seguinte maneira.

Event1 occurred! Object data: Hello World!

A funcionalidade adicional fornecida pelo Event module é ilustrado aqui. O exemplo de código a seguir ilustra o uso básico de Event.create para criar um evento e um método de disparador, adicionar dois manipuladores de eventos na forma de expressões lambda e em seguida, acionar o evento para executar ambas as expressões 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.")

A saída do código anterior é o seguinte.

Event occurred.
Given a value: Event occurred.

Processamento de fluxos de evento

Em vez de simplesmente adicionar um manipulador de eventos para um evento usando o Event.add função, você pode usar as funções do Event altamente personalizado para fluxos de processo de eventos no módulo de maneiras. Para fazer isso, você usar o pipe de encaminhamento (|>) juntamente com o evento, como o primeiro valor em uma série de chamadas de função e o Event funções do módulo como chamadas de função subseqüente.

O exemplo de código a seguir mostra como configurar um evento para o qual o manipulador é chamado somente sob determinadas condições.

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

O módulo observável contém funções semelhantes que operam nos objetos observáveis. Objetos observáveis são semelhantes aos eventos, mas somente ativamente assinar eventos se eles próprios estão sendo inscrito.

Consulte também

Referência

Expressões lambda: A diversão de palavra-chave (F#)

Módulo de Control.Event (F#)

Control.Event <'T>. Classe (F#)

Control.Event <' delegado,' Args > Classe (F #)

Conceitos

Membros (F#)

Eventos e representantes

Histórico de alterações

Date

History

Motivo

Janeiro de 2011

Enfatize o uso de eventos, em vez de DelegateEvent.

Aprimoramento de informações.