Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

Utilização de classe apenas para controlar eventos

Olá,

No meu projeto atual criei um método público AceitaNumeroPonto em uma classe ManipuladorEventos afim de reutilizar o método em diversos Forms no projeto.

Dentro da classe *.Designer.cs escrevi:

this.tbResistenciaConcreto.KeyPress += new System.Windows.Forms.KeyPressEventHandler(new ManipuladorEventos().AceitaNumeroPonto);

Percebi que não está sendo necessário utilizar o parênteses final *.AceitaNumeroPonto(). Qual motivo disso? Uma vez que o método recebe object sender e KeyPressEventArgs e como argumentos.

Em outra situação gostaria de utilizar um método com um argumento adicional aos dois tradicionais. Mas não sei como passaria dentro do Designer.cs.

this.tbResistenciaConcreto.KeyPress += new System.Windows.Forms.KeyPressEventHandler(new ManipuladorEventos().AceitaNumeroPonto(?, ?, 5));

Além disso, essa forma de trabalhar com eventos é adequada?

Agradeço desde já

2 respostas
solução!

Bom dia, José Moura. Tudo bom?

Aqui estamos lidando com Eventos, Delegates e, em sua última pergunta, expressões Lambda resolvem.

Eventos nos dão a capacidade de adicionar comportamento à alguns controles.

O evento KeyPress, por exemplo, é disparado sempre que o usuário pressiona uma tecla e, para implementar uma função que respeite a assinatura deste evento, você precisará implementar uma função com a mesma assinatura do delegate KeyPressEventHandler.

Um delegate nada mais é que a representação de um método ou uma função através de um objeto.

Quando você executa o código a seguir:

this.tbResistenciaConcreto.KeyPress += new KeyPressEventHandler(new ManipuladorEventos().AceitaNumeroPonto);

Você está criando uma nova instância do delegate KeyPressEventHandler passando o método AceitaNumeroPonto como argumento.

Vamos notar que seu argumento é o AceitaNumeroPonto e não o resultado da invocação deste método - para isto funcionar, seu método deverá retornar um delegate e você o invocará com abre-e-fecha parênteses.

O responsável por preencher os argumentos de seu método AceitaNumeroPonto será o TextBox tbResistenciaConcreto, ao invocar a lista de delegates associadas ao evento KeyPress.

Sobre a situação de utilizar um método com um argumento adicional, você está tentando criar uma função parcial de aplicação - nos termos da ciência da computação. Para isto, no c#, você pode usar o poder de expressões lambda e criar uma função que respeite a assinatura do delegate KeyPressEventHandler:

this.tbResistenciaConcreto.KeyPress += new KeyPressEventHandler(
    (sender, e) => 
        new ManipuladorEventos().AceitaNumeroPonto(sender, e, 5)
);

Com a expressão lambda, de baixo dos panos, o compilador está criando um método anônimo com uma assinatura que respeita o delegate KeyPressEventHandler e apenas invoca o método AceitaNumeroPonto passando adiante os argumentos sender e e com o valor 5 fixado.

Esta forma de trabalhar com eventos é adequada? Sim. Mas, será que você precisa sempre criar uma nova instância de ManipuladorEventos para isto? Estes manipuladores precisam mesmo serem métodos de instância? Você pode os criar como estáticos e usar a sintaxe new KeyPressEventHandler(ManipuladorEventos.AceitaNumeroPonto);

Att.,

Muito obrigado, Guilherme!

A resposta foi muito útil e esclarecedora.