Tapahtumat ovat toimintoja, jotka yleensä ilmoittavat ohjelman muuttuneesta tilasta. Niitä käytetään paljon graafisten (työpöytä)käyttöliittymien ohjelmoinnissa. Esim. painikkeen klikkaaminen laukaisee yleensä tapahtuman.
Tapahtumat eivät itse tee mitään, vaan sitä varten ovat tapahtumankäsittelijät. Tapahtumaa voisi verrata radioon ja tapahtumankäsittelijöitä kuuntelijoiksi. Yhdellä tapahtumalla (lähettäjä) voi olla useita käsittelijöitä (kuuntelijat) eivätkä käsittelijät tiedä toisistaan. Kukin käsittelijä reagoi tapahtumaan itsenäisesti.
Tapahtumat vaikuttavat Delegaatit instansseilta, mutta tapahtuman ja normaalin delegaatin käytössä on joitain eroja. Tapahtumat liittyvät lähettäjään ja siksi lähettäjän ulkopuolelta ei saisi
Tapahtumat tehdään delegaatilla EventHandler, joka ei ota argumenttia ja sen geneerisellä versiolla EventHandler
public class TapahtumaLuokka
{
// tapahtuma, joka ei ota argumenttia
public event EventHandler JotainTehty = delegate { };
// tapahtuma, joka ottaa argumenttina ArvoMuuttuiEventArgs-objektin
public event EventHandler<ArvoMuuttuiEventArgs> ArvoMuuttui = delegate { };
public string Nimi { get; set; }
private int arvo;
public int Arvo
{
get
{
return arvo;
}
set
{
if (arvo == value)
{
// jos uusi arvo on sama kuin vanha
// ei tehdä mitään
return;
}
// otetaan vanha arvo talteen
int vanha = arvo;
// sijoitetaan uusi arvo
arvo = value;
// ilmoitetaan muuttuneesta arvosta
ArvoMuuttui(this, new ArvoMuuttuiEventArgs(Nimi,vanha, arvo));
}
}
public TapahtumaLuokka(string nimi, int arvo)
{
Nimi = nimi;
this.arvo = arvo;
}
public void TeeJotain()
{
// tässä tehdään jotain
Console.WriteLine("{0} tekee jotain", Nimi);
// ilmoitetaan, että jotain on tehty
JotainTehty(this, EventArgs.Empty);
}
}
Argumenttina annettava luokka kokoaa tapahtumaan liittyvät tiedot yhteen. Tällaisen luokan nimen tulisi päättyä EventArgs. Esim. luokka, joka kokoaa yhteen muuttuneen arvon tietoja.
public class ArvoMuuttuiEventArgs : EventArgs
{
// olion nimi
public string Nimi { get; set; }
// vanha arvo
public int Vanha { get; set; }
// uusi arvo
public int Uusi { get; set; }
public ArvoMuuttuiEventArgs(string nimi, int vanha, int uusi)
{
Nimi = nimi;
Vanha = vanha;
Uusi = uusi;
}
}
Ja vielä käyttöesimerkki.
class Program
{
static void Main(string[] args)
{
TapahtumaLuokka t1 = new TapahtumaLuokka("eka", 1);
// lisätään tapahtumankäsittelijä
t1.JotainTehty += new EventHandler(t1_JotainTehty);
// lisätään tapahtumankäsittelijä
t1.ArvoMuuttui += new EventHandler<ArvoMuuttuiEventArgs>(testi_ArvoMuuttui);
t1.TeeJotain();
t1.Arvo = 10;
}
static void t1_JotainTehty(object sender, EventArgs e)
{
Console.WriteLine("t1 teki jotain");
}
// huomaa argumenttina tuleva ArvoMuuttuiEventArgs
static void testi_ArvoMuuttui(object sender, ArvoMuuttuiEventArgs e)
{
Console.WriteLine("{0}:n vanha arvo oli {1} ja uusi arvo on {2}",e.Nimi, e.Vanha, e.Uusi);
}
}
Lisätään edellä olleeseen TapahtumaLuokkaan nuo aksessorit
public class TapahtumaLuokka2
{
// tapahtuma, joka ottaa argumentin
private event EventHandler<ArvoMuuttuiEventArgs> arvoMuuttui = delegate { };
public event EventHandler<ArvoMuuttuiEventArgs> ArvoMuuttui
{
add
{
// lisätään käsittelijä
arvoMuuttui += value;
Console.WriteLine("Lisätty käsittelijä: {0}", value.Method.Name);
}
remove
{
// poistetaan käsittelijä
arvoMuuttui -= value;
Console.WriteLine("Poistettu käsittelijä: {0}", value.Method.Name);
}
}
}