sexta-feira, 27 de abril de 2007

C# - Implementando suporte a eventos na sua classe

Olá novamente a todos. Neste post vou escrever sobre uma técnica interessante e com certeza muito útil no desenvolvimento de componentes - Eventos.

Nas linguagens de programação e IDEs modernas nós trabalhamos com eventos o tempo todo - OnClick do botão, OnChange da caixa de texto, etc...

Vamos fazer um pequeno exemplo. Vou criar uma classe chamada Figura, que representa uma figura com os eixos X, Y e Z.

class Figura {

// eixos da figura
private float eixoX = 0;
private float eixoY = 0;
private float eixoZ = 0;

// contrutor da classe
public Figura(float a, float b, float c) {
eixoX = a;
eixoY = b;
eixoZ = c;
}


// métodos que invertem os eixos
public void InverterX() {
eixoX = -eixoX;
AposInverter("X invertido");
}

public void InverterY() {
eixoY = -eixoY;
AposInverter("Y invertido");
}

public void InverterZ() {
eixoZ = -eixoZ;
AposInverter("Z invertido");
}

// definição do evento AposInverter
public delegate void FigureHandler(string msg);
public static FigureHandler AposInverter;
}

Esta classe (Figura) possui 3 campos de dados (eixoX, eixoY e eixoZ), 3 métodos (InverterX, InveterY e InterterZ) e 1 evento (AposInverter)

Vamos detalhar um pouco a declaração do evento AposInverter:

1. definimos o delegate do método a ser executado para o evento.
Delegate, resumidamente, representa uma chamada à execução de um método. Na linguagem C++ há um recurso parecido chamado callback function, que representa um apontamento (ponteiro) para um método. Em PHP também há um recurso semelhante que eu exemplifiquei neste post. Em C# a implementação é mais elegante e protegida também. O delegate é um tipo em C#; nós temos que definir o delegate em tempo de desenvolvimento.

Vamos rever o delegate:


public delegate void FigureHandler(string msg);


Neste caso o delegate FigureHandler é um método sem retorno (void) que aceita um parâmetro (string msg).

Nos métodos InveterX, InveterY e InverterZ temos o disparo do evento AposInveter informando o que foi invertido. Com isso podemos criar na nossa classe principal uma função que é executada quando este evento acontece, podendo assim agir de acordo com a inversão dos eixos.

Vamos ver a implementação na classe principal:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace DelegatesApp {
public partial class Form1 : Form {

private Figura figura;

public Form1() {
InitializeComponent();

figura = new Figura(10, 20, 30);
Figura.AposInverter += new Figura.FigureHandler(figura_AposInverter);
}

private static void figura_AposInverter(string msg) {
MessageBox.Show(msg);
}

private void button1_Click(object sender, EventArgs e) {
figura.InverterX();
}

private void button2_Click(object sender, EventArgs e) {
figura.InverterY();
}

private void button3_Click(object sender, EventArgs e) {
figura.InverterZ();
}

}
}

Esta classe representa um Windows Form de uma Windows Application em C#.

Primeiro temos um campo privado dla classe figura do tipo Figura (nossa classe criada).
No construtor da classe Form1 criamos uma instância da classe Figura na variável figura e conectamos o método figura_AposInverter ao evento AposInverter da classe Figura

private static void figura_AposInverter(string msg) {
MessageBox.Show(msg);
}

Aqui criamos o método no modelo do manipulador de evento (delegate) da classe.

Então no evento Click dos botões invertemos cada um dos eixos. O comportamento esperado do programa é chamar um MessageBox.Show() a cada inversão de eixo.

Então é isso. Particularmente eu achei muito simples a forma de implementar algo tão útil no desenvolvimento.

Abraços a todos e, como sempre, fiquem à vontade para comentar e participar.

Nenhum comentário:

Postar um comentário

 
BlogBlogs.Com.Br