Enhver der arbejder med C# tænker helt automatisk i metoder og attributter, når der designes klasser. Med denne lille artikkel vil jeg gerne give dig et hurtigt indblik i Events og Delegates, så du fremadrettet også begynder at tænke i Events når du designer klasser.
Hvad er en Event
Event oversættes til dansk som en hændelse, altså noget der er sket. Det er også sådan du skal opfatte det. Du kan i din klasse angive at noget er sket:
- en attribut har skiftet værdi,
- en tærskel værdi er overskredet,
- et kald til en metode er foretaget,
du kan sikkert komme på mere selv.
Implementering af Event.
Du angiver at din klasse stiller Events tilrådighed således:
public event BusinessObjectEventHandler OnEvent;
BusinessObjectEventHandler : navnet på den delegates der beskriver hvordan klienter abonnerer på din Event.
Event : beskriver hvorfor eventen er opstået. Herunder er nogle eksempler.
OnChange ved ændringer af en attribut værdi.
OnTick ved ændring i tid
OnMaxReached ved opnåelse af tærskel værdi.
OnClick ved bruger interaktion med mus.
OnKeyPressed ved bruger interaktion med tastatur.
Angiv callback funktionen med en delegate
En delegate er interface definitionen til callback funktionen der aktiveres af din event.
public delegate void BusinessObjectEventHandler(object sender, EventArgs e)
Publisering af Event
Når en event har fundet sted skal den publiseres så alle der abonnerer på den kan foretage det de har implementeret i deres callback funktion.
F.eks. hvis jeg i min klasse har implementeret denne event,
public event BusinessObjectEventHandler OnChanged;
som skal publiseres når en attribut skifter værdi, sikrer jeg at det sker når attributten sættes.
private string _firstName;
public string firstName
{
get { return this._ firstName; }
set {
if (OnChanged != null)
OnChanged(this, new EventArgs());
this._ firstName = value;
}
}
Abonnering på en Event
Den klient der instantierer klassen skal abonnere på eventen før det kommer til at ske noget.
Lad os sige at Eventen tilhører klassen Person. Man angiver at man gerne vil abonnere på eventen OnChanged ved at fortælle eventen hvilke callback metode der skal kaldes når event fyres af.
Herunder er der angivet to metoder der hver især skal kaldes, person_Onchanged_1, person_Onchanged_2.
class Person person = new Person();
person.OnChanged += new BusinessObjectEventHandler(person_Onchanged_1);
person.OnChanged += new BusinessObjectEventHandler(person_Onchanged_2);
private void person_Onchanged_1(object sender, EventArgs e){
//do stuff//
}
private void person_Onchanged_2(object sender, EventArgs e){
//do stuff//
}
Denne event anvender EventArgs som ikke indeholder data. Det vil typisk være at foretrække at data sendes med i EventArgs, det gør det muligt for abonnenterne at foretage mere detaljerede valg baseret på aktuelle data.
Event med data
For at få data med når dit event fyres af, skal du lave en klasse der arver fra EventArgs
public class BusinessObjectEventArgs : EventArgs
{
private string _oldname;
private string _newname;
private string _changedby;
public BusinessObjectEventArgs(
string oldname,
string newname,
string changedby)
{
_oldname = oldname;
_newname = newname;
_changedby = changedby;
}
public string oldname{
get {
return _oldname;
}
}
public string newname{
get {
return _ newname;
}
}
public string changedby{
get {
return _ changedby;
}
}
}
Det betyder så også at din delegate ser anderledes ud nu, da den nu anvender BusinessObjectEventArgs.
public delegate void BusinessObjectEventHandler(object sender, BusinessObjectEventArgs e)
I din klasse skal du sætte værdierne i din BusinessObjectEventArgs inden eventen fyres af.
private string _firstName;
public string firstName
{
get { return this._ firstName; }
set {
if (OnChanged != null)
{
OnChanged(
this,
new BusinessObjectEventArgs(
_firstname,
value, WindowsIdentity.GetCurrent().Name)
);
}
this._ firstName = value;
}
}
Data er nu tilgængelige for callback funktionen via instansen e af BusinessObjectEventArgs.
private void i_OnChanged2(
object sender,
BusinessObjectEventArgs e)
{
Print e.oldname;
Print e.newname;
Print e.Changedby;
}