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 delegaatin 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

[list bullet=”circle”]

  • uudelleen asettaa (käyttäen = -operaattoria) tapahtumankäsittelijöitä, vaan niitä pitäisi pystyä vain lisäämään (+=) ja poistamaan (-=)
  • nollata (olio.Tapahtuma = null;) tapahtumankäsittelöitä
  • kutsua tapahtumaa
  • [/list]

    Tapahtumat tehdään delegaatilla EventHandler, joka ei ota argumenttia ja sen geneerisellä versiolla EventHandler<T>, jossa T on argumenttina annettava luokka. Tämän lisäksi tarvitaan avainsana event.

    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);
    	}
    }
    

    add- ja remove-aksessorit

    Tapahtumankäsittelijöiden lisäämiseen ja poistamiseen saa enemmän hallintaa, kun lisää add- ja remove-aksessorit, jotka muistuttavat pitkälti ominaisuuksien get- ja set-aksessoreita.

    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);
    		}
    	}
    }
    
    u7x9cc0

    Navigointi

    Social Media