Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Os eventos no .NET são baseados no modelo delegado. O modelo de delegado segue o padrão de design de observador , que permite que um assinante se registre e receba notificações de um provedor. Um remetente de evento envia uma notificação por push quando ocorre um evento. Um recetor de evento define a resposta. Este artigo descreve os principais componentes do modelo delegado, como consumir eventos em aplicativos e como implementar eventos em seu código.
Gerar eventos com um remetente de eventos
Um evento é uma mensagem enviada por um objeto para sinalizar a ocorrência de uma ação. A ação pode ser interação do usuário, como pressionar um botão, ou pode resultar de outra lógica do programa, como uma alteração de valor de propriedade. O objeto que gera o evento é chamado de remetente do evento . O remetente do evento não conhece o objeto ou método que recebe (manipula) os eventos que gera. Normalmente, o evento está associado ao remetente do evento. Por exemplo, o evento Click é um membro da classe Button e o evento PropertyChanged é um membro da classe que implementa a interface INotifyPropertyChanged.
Para definir um evento, utilize a palavra-chave de evento C# ou a palavra-chave Event do Visual Basic na assinatura da classe do seu evento e especifique o tipo de delegado para o evento. Os delegados são descritos na próxima seção.
Normalmente, para gerar um evento, você adiciona um método marcado como protected
e virtual
(em C#) ou Protected
e Overridable
(no Visual Basic). A convenção de nomenclatura para o método é On<EventName>
, como OnDataReceived
. O método deve usar um parâmetro que especifica um objeto de dados de evento, que é um objeto do tipo EventArgs ou um tipo derivado. Você fornece esse método para permitir que classes derivadas substituam a lógica para gerar o evento. Uma classe derivada deve sempre chamar o método On<EventName>
da classe base para garantir que os delegados registrados recebam o evento.
O exemplo a seguir mostra como declarar um evento chamado ThresholdReached
. O evento está associado ao delegado EventHandler e ocorre num método denominado OnThresholdReached
.
class Counter
{
public event EventHandler ThresholdReached;
protected virtual void OnThresholdReached(EventArgs e)
{
ThresholdReached?.Invoke(this, e);
}
// provide remaining implementation for the class
}
Public Class Counter
Public Event ThresholdReached As EventHandler
Protected Overridable Sub OnThresholdReached(e As EventArgs)
RaiseEvent ThresholdReached(Me, e)
End Sub
' provide remaining implementation for the class
End Class
Declarar assinaturas de delegados para manipuladores de eventos
Um delegado é um tipo que armazena uma referência a um método. Um/uma delegado/a é declarado/a com uma assinatura que mostra o tipo de retorno e os parâmetros dos métodos que referencia. Ele pode conter referências apenas a métodos que correspondam à sua assinatura. Um delegado é equivalente a um ponteiro de função de tipo seguro ou a um retorno de chamada. Uma declaração de delegado é suficiente para definir uma classe de delegado.
Os delegados têm muitos usos no .NET. No contexto de eventos, um delegado é um intermediário (ou mecanismo semelhante a um ponteiro) entre a fonte do evento e o código que manipula o evento. Você associa um delegado a um evento incluindo o tipo de delegado na declaração de evento, conforme mostrado no exemplo da seção anterior. Para obter mais informações sobre delegados, consulte a classe Delegate.
O .NET fornece os delegados EventHandler e EventHandler<TEventArgs> para dar suporte à maioria dos cenários de eventos. Use o delegado EventHandler para todos os eventos que não incluem dados de evento. Utilize o delegado EventHandler<TEventArgs> para eventos que incluam dados sobre o evento. Esses delegados não têm valor de tipo de retorno e usam dois parâmetros (um objeto para a origem do evento e um objeto para dados de evento).
Os delegados são multicast objetos de classe, o que significa que eles podem conter referências a mais de um método de manipulação de eventos. Para obter mais informações, consulte a página de referência Delegate. Os delegados oferecem flexibilidade e controle refinado no tratamento de eventos. Um delegado atua como um despachante de eventos para a classe que gera o evento, mantendo uma lista de manipuladores de eventos registados para o evento.
Use os tipos de delegado EventHandler e EventHandler<TEventArgs> para definir o delegado necessário. Você define um delegado com o tipo delegate
em C# ou o tipo Delegate
em Visual Basic na declaração. O exemplo a seguir mostra como declarar um delegado chamado ThresholdReachedEventHandler
:
public delegate void ThresholdReachedEventHandler(object sender, ThresholdReachedEventArgs e);
Public Delegate Sub ThresholdReachedEventHandler(sender As Object, e As ThresholdReachedEventArgs)
Trabalhar com classes de dados de eventos
Os dados associados a um evento podem ser fornecidos por meio de uma classe de dados de evento. O .NET fornece muitas classes de dados de evento que você pode usar em seus aplicativos. Por exemplo, a classe SerialDataReceivedEventArgs é a classe de dados de evento para o evento SerialPort.DataReceived. O .NET segue um padrão de nomenclatura em que todas as classes de dados de eventos terminam com o sufixo EventArgs
. Você determina qual classe de dados de evento está associada a um evento examinando o delegado do evento. Por exemplo, o SerialDataReceivedEventHandler delegado inclui a classe SerialDataReceivedEventArgs como parâmetro.
A classe EventArgs é normalmente o tipo base para classes de dados de eventos. Você também usa essa classe se um evento não tiver nenhum dado associado a ele. Quando você cria um evento que notifica os assinantes de que algo aconteceu sem dados adicionais, inclua a classe EventArgs como o segundo parâmetro no delegado. Você pode passar o valor EventArgs.Empty quando nenhum dado é fornecido. O delegado EventHandler inclui a classe EventArgs como parâmetro.
Você pode criar uma classe que deriva da classe EventArgs para fornecer quaisquer membros necessários para passar dados relacionados ao evento. Normalmente, você deve usar o mesmo padrão de nomenclatura do .NET e finalizar o nome da classe de dados do evento com o sufixo EventArgs
.
O exemplo a seguir mostra uma classe de dados de evento chamada ThresholdReachedEventArgs
que contém propriedades específicas para o evento que está sendo gerado:
public class ThresholdReachedEventArgs : EventArgs
{
public int Threshold { get; set; }
public DateTime TimeReached { get; set; }
}
Public Class ThresholdReachedEventArgs
Inherits EventArgs
Public Property Threshold As Integer
Public Property TimeReached As DateTime
End Class
Responder a eventos com manipuladores
Para responder a um evento, defina um método de manipulador de eventos no recetor de eventos. Esse método deve corresponder à assinatura do delegado para o evento que você está manipulando. No manipulador de eventos, você executa as ações necessárias quando o evento é gerado, como coletar a entrada do usuário depois que o usuário pressiona um botão. Para receber notificações quando o evento ocorre, seu método manipulador de eventos deve se inscrever no evento.
O exemplo a seguir mostra um método manipulador de eventos chamado c_ThresholdReached
que corresponde à assinatura do EventHandler delegado. O método subscreve o evento ThresholdReached
:
class ProgramTwo
{
static void Main()
{
var c = new Counter();
c.ThresholdReached += c_ThresholdReached;
// provide remaining implementation for the class
}
static void c_ThresholdReached(object sender, EventArgs e)
{
Console.WriteLine("The threshold was reached.");
}
}
Module Module1
Sub Main()
Dim c As New Counter()
AddHandler c.ThresholdReached, AddressOf c_ThresholdReached
' provide remaining implementation for the class
End Sub
Sub c_ThresholdReached(sender As Object, e As EventArgs)
Console.WriteLine("The threshold was reached.")
End Sub
End Module
Usar manipuladores de eventos estáticos e dinâmicos
O .NET permite que os assinantes se registrem para notificações de eventos de forma estática ou dinâmica. Os manipuladores de eventos estáticos estão ativos durante toda a vida da classe cujos eventos eles manipulam. Os manipuladores de eventos dinâmicos são explicitamente ativados e desativados durante a execução do programa, geralmente em resposta a alguma lógica condicional do programa. Você pode usar manipuladores dinâmicos quando as notificações de eventos são necessárias apenas sob determinadas condições ou quando as condições de tempo de execução determinam o manipulador específico a ser chamado. O exemplo na seção anterior mostra como adicionar dinamicamente um manipulador de eventos. Para obter mais informações, consulte Eventos (em Visual Basic) e Eventos (em C#).
Acionar vários eventos
Se sua classe gerar vários eventos, o compilador gerará um campo por instância de representante de evento. Se o número de eventos for grande, o custo de armazenamento de um campo por delegado pode não ser aceitável. Para esses cenários, o .NET fornece propriedades de evento que você pode usar com outra estrutura de dados de sua escolha para armazenar representantes de eventos.
As propriedades dos eventos consistem em declarações de eventos acompanhadas por métodos de acesso a eventos. Os acessadores de eventos são métodos que você define para adicionar ou remover instâncias delegadas de eventos da estrutura de dados de armazenamento.
Observação
As propriedades do evento são mais lentas do que os campos de evento porque cada event delegate deve ser obtido antes de poder ser invocado.
A troca é entre memória e velocidade. Se sua classe define muitos eventos que são gerados com pouca frequência, você deve implementar propriedades de evento. Para obter mais informações, consulte Manipular vários eventos usando propriedades de evento.
Explorar tarefas relacionadas
Os recursos a seguir descrevem outras tarefas e conceitos relacionados ao trabalho com eventos:
- Gerar e consumir eventos: Encontre exemplos para gerar e consumir eventos.
- Manipular vários eventos com propriedades de evento: Descubra como usar propriedades de evento para manipular vários eventos.
- Explore o padrão de design do observador: Revise um padrão de design que permite que um assinante se registre e receba notificações de um provedor.
Revisão da especificação de referência
A documentação de referência de especificação está disponível para as APIs que oferecem suporte à manipulação de eventos:
Nome da API | Tipo de API | Referência |
---|---|---|
Manipulador de eventos | Delegado | EventHandler |
TEventArgs EventHandler<> | Delegado | EventHandler<TEventArgs> |
EventArgs | Classe | EventArgs |
Delegado | Classe | Delegate |
Conteúdo relacionado
- Eventos (Visual Basic)
- Eventos (Guia de Programação em C#)
- Visão geral de eventos e eventos roteados - de aplicativos da Plataforma Universal do Windows (UWP)
- Eventos nas aplicações da Windows Store 8.x