Eventos

No início, a programação era puramente linear, ou seja, o código era executado de forma sequencial, linha após linha. Nas aplicações console ainda podemos ver códigos deste tipo, uma vez que se dispõe apenas de uma tela na qual se exibe caracteres e a única forma de interação do usuário é utilizando o teclado para inserir dados quando solicitado.

Exemplo de programa linear

Figura 1: Exemplo de programa linear

A Figura 1 mostra um exemplo de aplicação linear. Os dados do cliente são inseridos sempre na sequência exibida, o usuário não pode optar por digitar primeiro o email, por exemplo.

Com o advento das interfaces mais completas, contendo botões, caixas de texto, entre outros elementos gráficos diversos, o código das aplicações passou a ser dividido blocos que são executados de acordo com a interação do usuário (clicando em um botão, por exemplo).

Exemplo de aplicação não linear

Figura 2: Exemplo de aplicação não linear

Já a Figura 2 exibe a interface de uma janela que tem a mesma finalidade da tela ilustrada na figura anterior. Porém, neste exemplo, o usuário pode optar por inserir os dados na ordem que preferir, bem como pode clicar nas opções “Salvar” e “Cancelar” a qualquer momento, não só após concluir a inserção das informações.

Nesse caso, o processamento dos dados e a gravação ou não destes, será feito quando o usuário clicar em um dos botões. O programador não pode prever quando e se isso ocorrerá, mas um bloco de código deverá ser executado quando o botão for pressionado.

De fato, quando o usuário clica em um botão, um evento chamado Click é disparado e é neste evento que o programador trabalhará para executar suas rotinas específicas.

Um evento é “algo” que ocorre em consequência de uma ação, no exemplo citado, a ação é o pressionamento do botão.

Observação: o leitor pode achar um pouco repetitivo o uso da expressão “evento”, e de fato é, mas esta é a forma mais simples de expor o assunto.

Fazendo referência ao mundo físico, podemos citar o seguinte exemplo: ao girar a chave na ignição de um veículo, o mesmo é ligado. A ação, neste caso, de girar a chave fez com que o evento da ligação do veículo fosse executado. Porém, ao ligar o veículo, outras coisas precisam ser feitas, tais como acender as luzes do painel. Então, trazendo o exemplo para o contexto da programação, podemos considerar Veiculo como uma classe e Veiculo_Ligado como sendo o evento que ocorre ao girar a chave. O código deste evento seria, por exemplo, semelhante ao da Listagem 1.

Listagem 1: Representação em código de um evento

CLASSE Veiculo
	EVENTO Veiculo_Ligado
		Acender_Luzes_Painel();
		//Outros procedimentos
	FIM_EVENTO
FIM_CLASSE

No .NET Framework, são diversos os eventos que podem ser disparados durante uma aplicação. Eventos ocorrem, por exemplo, ao pressionar um botão, como já foi dito, ao alterar o texto de um campo, ao abrir e fechar um form e em várias outras situações.

Os objetos que os disparam (chamados event senders), porém, não sabem o que deve ser feito quando certo evento ocorrer, é necessário que se informe qual método (chamado de event handler) será executado a cada ocorrência deste evento. Essa não é uma tarefa difícil e fazemos isso todo dia, até de forma automática.

Crie uma “Windows Forms Application” e adicione apenas um botão (que deve ser chamar button1, por padrão) à tela. Então dê um duplo clique sobre o botão, e você será redirecionado para o código do formulário, onde a programação em si é feita. Será criado um método void no código do form, como exibido na Listagem 2.

Listagem 2: Métodos criados ao dar dois cliques sobre um botão

//Em C#
private void button1_Click(object sender, EventArgs e)
{
}

'Em VB.NET
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
End Sub

Em VB.NET, vemos que na assinatura do método consta um trecho “Handles Button1.Click”, ou seja, este método está tratando o evento Click do botão. Então, quando o usuário clicar no botão, o código que estiver no corpo do método Button1_Click será executado. Simples assim.

Na linguagem C#, porém, nada faz referência ao botão (a não ser o nome do método, o que não significa muito), então como sabemos que este método será executado no evento Click do button1? No caso do C#, a resposta está um pouco menos explícita. É preciso abrir o arquivo Form1.Designer.cs (este arquivo pode ser encontrado na guia Solution Explorer, expandindo o item Form1, como ilustrado na Figura 3).

Arquivo Designer do form no Solution Explorer

Figura 3: Arquivo Designer do form no Solution Explorer

Neste arquivo, veremos um trecho semelhante ao exibido na Figura 4.

Ligação do evento Click ao método button1_Click

Figura 4: Ligação do evento Click ao método button1_Click

A linha em destaque nos mostra que “somamos” ao evento Click um objeto do tipo EventHandler que recebe como parâmetro o método criado anteriormente. Esta é a sintaxe utilizada, em C# para associar um método a um evento. Vamos então definir alguns métodos e ligá-los aos eventos manualmente, isso facilitará o entendimento de como funciona.

No código do form, adicione os seguintes métodos:

Listagem 3: Métodos para tratar o evento Click do botão

//Em C#
private void metodo_click1(object sender, EventArgs e)
{
    MessageBox.Show("Método 1");
}

private void metodo_click2(object sender, EventArgs e)
{
    MessageBox.Show("Método 2");
}

'Em VB.NET
Private Sub metodo_click1(sender As System.Object, e As System.EventArgs)
   MessageBox.Show("Método 1")
End Sub

Private Sub metodo_click2(sender As System.Object, e As System.EventArgs)
   MessageBox.Show("Método 2")
End Sub

Note que na versão em VB.NET não há o “Handles Button1.Click”, pois estes métodos não são especificamente para tratar o evento Click do botão, porém, os utilizaremos para esta finalidade.

Agora, no evento Load do form (dando dois cliques no formulário principal), vamos associar um dos métodos ao evento do botão, conforme mostra a Listagem 4.

Listagem 4: Associando um método a um evento manualmente

//Em C#
private void Form1_Load(object sender, EventArgs e)
{
    button1.Click += new EventHandler(metodo_click1);
}

'Em VB.NET
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
    AddHandler Me.Button1.Click, AddressOf Me.metodo_click1
End Sub

Executando o projeto e clicando no botão, teremos uma caixa de diálogo com o texto “Método 1”. Sugiro então que o leitor troque o parâmetro “método_click1” para “método_click2” e execute novamente o projeto, dessa vez a mensagem será “Método 2”, pois o método associado ao evento será o método_click2.

Neste ponto pode surgir uma dúvida bastante comum: é possível então associar mais de um método a um mesmo evento? A resposta é SIM. Como vimos, os métodos são “somados” ao evento através dos operadores “+=” e “AddHandler”. Então, faça você mesmo o teste e adicione os dois métodos ao evento (uma linha para cada método) e execute o projeto. As duas mensagens serão exibidas.

A Listagem 4 nos permite observar e compreender a sintaxe, nas duas linguagens, para se “adicionar” um método a um evento. Na prática, o que se faz é informar ao objeto, uma referência ao método que tratará seu evento. Em C++, por exemplo, existem os chamados ponteiros para funções, que têm o mesmo objetivo. No .NET Framework, porém, estes ponteiros têm outro nome: delegate.

Delegates

Neste ponto do artigo, já passamos pelos delegates sem conhecê-los como tal. Lembra do EventHandler? Ele é um delegate, que não passa de um objeto que referencia um método de acordo com sua assinatura (retorno e parâmetros). Repare que todos os métodos que definimos para tratar o evento Click do botão tem retorno void e recebem dois parâmetros. O fizemos desta forma pois o delegate EventHandler foi definido para referenciar métodos com esta estrutura.

A Listagem 5 mostra a declaração do EventHandler no namespace System.

Listagem 5: Declaração do delegate EventHandler

//Em C#
public delegate void EventHandler(Object sender, EventArgs e);

'Em VB.NET
Public Delegate Sub EventHandler (sender As Object, e As EventArgs)

Assim, os métodos responsáveis por tratar os eventos que utilize o EventHandler devem possuir esta assinatura para que a operação seja válida. Outros eventos utilizam outros delegates como DragEventHandler e o KeyEventHandler.

Na Listagem 5 podemos também aprender a sintaxe de declaração de um delegate nas duas linguagens.

Métodos anônimos

Por fim, veremos rapidamente como trabalhar com os chamados métodos anônimos que foram adicionados na versão 2.0 do C# (não estão disponíveis nativamente para VB.NET) e nos permitem criar delegates que não referenciam diretamente um método previamente definido, e sim um bloco de código (com a mesma função do método). Vejamos na prática, com o mesmo exemplo do botão visto anteriormente, como funciona esta forma de tratamento de eventos.

No evento Load do form, onde fizemos referência aos métodos método_click1 e método_click2, vamos substituir o código pelo conteúdo da Listagem 6.

Listagem 6: Método anônimo para tratar o evento Click do botão

private void Form1_Load(object sender, EventArgs e)
{
    button1.Click += delegate(Object sd, EventArgs ea)
                    {
                        MessageBox.Show("Método anônimo");
                    };
}

Repare que mesmo se tratando de um método anônimo (não há prévia declaração), os parâmetros devem coincidir com a declaração do delegate responsável pelo tratamento do evento, no caso, o EventHandler. Apenas os nomes dos parâmetros foram alterados, pois já existem o “sender” e o “e” do método Form1_Load, dentro do qual o delegate foi criado.

Conclusão

A possibilidade de definir métodos para tratar eventos de forma manual e dinâmica é bastante útil, por exemplo, quando criamos objetos em tempo de execução e precisamos que rotinas sejam executadas mediante a interação do usuário com estes objetos.

Concluo assim este artigo no qual foram apresentados os eventos (Events), delegados (Delegates) e métodos anônimos (Anonymous Methods) na plataforma .NET. Espero que o conteúdo possa ser útil.

Agradeço a atenção do leitor e me despeço por aqui.