Podnoszenie zdarzenie
Jeśli chcesz, aby klasy, aby wygenerować zdarzenie, należy podać trzy następujące elementy:
Klasa, która dostarcza dane zdarzenie.
Delegata zdarzenia.
Klasa, która wywołuje zdarzenie.
Definiowanie klasy, aby dostarczyć dane zdarzenie
Przez Konwencję w .NET Framework, gdy zdarzenie jest wywoływane, przekazuje dane zdarzeń do jego obsługi zdarzeń. Dane zdarzenia są dostarczane przez System.EventArgs klasy lub przez klasę, która jest uzyskane z niego.
Często zdarzenia nie zawiera niestandardowych danych; fakt, że zdarzenie zostało wywołane zawiera wszystkie informacje, które wymagają obsługi zdarzeń. W takim przypadku można przekazać zdarzenia EventArgs obiektu do jego obsługi. EventArgs Klasy ma tylko jeden składnik, Empty, to znaczy nie są dziedziczone z System.Object. Mogą być używane do utworzenia wystąpienia nowego EventArgs klasy.
Jeśli zdarzenie niestandardowe dane, można przekazać instancję klasy pochodzącej od EventArgs do obsługi zdarzeń. W zależności od dokładne dane zdarzenie przechodzi do obsługi może być mogli korzystać z istniejącej klasy danych zdarzeń w .NET Framework. Na przykład, jeśli modułu obsługi zdarzenia pozwala na akcję skojarzoną ze zdarzeniem odwołana, można użyć CancelEventArgs klasy.
Kiedy należy podać dane niestandardowe do obsługi i istniejącej klasy nie jest dostępna, można zdefiniować własne klasy danych zdarzenia. Musi pochodzić od System.EventArgs. Umownie, nosi nazwę tej klasy EventNameEventArgs. Poniższy przykład ilustruje takie klasy danych zdarzenia niestandardowego. Definiuje klasę o nazwie AlarmEventArgs , która zapewnia dwie pozycje danych do obsługi zdarzeń: tylko do odczytu Time właściwość, która wskazuje, kiedy alarm minął; i Snooze właściwość, która wskazuje, czy alarmu należy go ponownie po upływie wyznaczonego czasu lub czy anulowane przyszłych alarmów.
Public Class AlarmEventArgs : Inherits EventArgs
Private alarmTime As Date
Private snoozeOn As Boolean = True
Public Sub New(time As Date)
Me.alarmTime = time
End Sub
Public ReadOnly Property Time As Date
Get
Return Me.alarmTime
End Get
End Property
Public Property Snooze As Boolean
Get
Return Me.snoozeOn
End Get
Set
Me.snoozeOn = value
End Set
End Property
End Class
public class AlarmEventArgs : EventArgs
{
private DateTime alarmTime;
private bool snoozeOn = true;
public AlarmEventArgs(DateTime time)
{
this.alarmTime = time;
}
public DateTime Time
{
get { return this.alarmTime; }
}
public bool Snooze
{
get { return this.snoozeOn; }
set { this.snoozeOn = value; }
}
}
public ref class AlarmEventArgs : public EventArgs
{
private:
System::DateTime^ alarmTime;
bool snoozeOn;
public:
AlarmEventArgs(System::DateTime^ time)
{
this->alarmTime = time;
this->snoozeOn = true;
}
property DateTime^ Time
{
System::DateTime^ get()
{ return this->alarmTime; }
}
property bool Snooze
{
bool get()
{ return this->snoozeOn; }
void set(bool snooze)
{ this->snoozeOn = snooze; }
}
};
Definiowanie delegata zdarzenia
Pełnomocnika zdarzeń jest używany do definiowania podpisu zdarzenia. Pełnomocnik określonego zdarzenia zazwyczaj odpowiada klasy danych określonego zdarzenia. Umownie zdarzeń w .NET Framework mają podpis EventName(sender, e), gdzie sender jest Object , która zapewnia odwołanie do klasy lub struktury, że wyzwolenie zdarzenia, i e jest EventArgs obiektu lub obiektu pochodzących z EventArgs zapewnia dane zdarzenie. Następnie definicję delegata zwykle ma postać EventNameHandler(sender, e).
Jeśli używasz klasy danych zdarzenia, który jest już zdefiniowana w.NET Framework class library lub w bibliotece strony trzeciej, jest prawdopodobne, że odpowiedniego delegata zdarzenia jest także zdefiniowane w tej bibliotece. Na przykład EventHandler pełnomocnik może być używany razem z EventArgs klasy. Podobnie CancelEventHandler pełnomocnik może być używany razem z CancelEventArgs klasy.
Jeżeli zdefiniowanie klasy danych zdarzenia niestandardowego, można także zdefiniować niestandardowe pełnomocnika do definiowania podpisu zdarzenia lub można użyć rodzajową Action<T1, T2> delegować.
Poniższy przykład definiuje delegata zdarzenia o nazwie AlarmEventHandler.
Public Delegate Sub AlarmEventHandler(sender As Object, e As AlarmEventArgs)
public delegate void AlarmEventHandler(object sender, AlarmEventArgs e);
public delegate void AlarmEventHandler(System::Object^ sender, AlarmEventArgs^ e);
Definiowanie klasy podnieść zdarzenia
Klasa, która wywołuje zdarzenie musi dostarczyć deklarację zdarzenia i zdefiniować metodę, która wywołuje zdarzenie. Dodatkowo musi ono zapewnić logikę podnieść zdarzenia w klasie właściwości lub metody.
Określenie członka zdarzeń w sieci za pomocą klasy event słowa kluczowego w C# lub Event instrukcję w języku Visual Basic. Gdy kompilator napotka deklaracji zdarzenia w klasie, tworzy członek prywatny takich jak:
private EventNameHandler eh = null;
Kompilator tworzy również dwie metody publiczne, add_EventName i remove_EventName. Metody te są zdarzeń haków ładunkowych, zezwalające na delegatów, które mają być połączone lub usuwane z delegata zdarzenia eh. Szczegóły są ukryte przed programista.
Uwaga
W językach innych niż C# i Visual Basic 2005, kompilator nie może automatycznie wygenerować kod odpowiadający członka zdarzeń i trzeba jawnie zdefiniować zdarzeń haków ładunkowych i pola prywatne delegata.
Poniższy przykład deklaruje zdarzenia o nazwie AlarmEvent. Jest fragmentem z przykład klasę o nazwie Alarm którego pełnego kodu źródłowego jest pokazany poniżej. Należy zauważyć, że ma podpis z AlarmEventHandler delegować.
Event AlarmEvent As AlarmEventHandler
public event AlarmEventHandler AlarmEvent;
public:
event AlarmEventHandler^ AlarmEvent;
Po zdefiniowaniu implementacji zdarzenia, należy określić, kiedy zdarzenie. Podnoszenie zdarzenie, wywołując chronionego OnEventName metoda w klasie zdefiniowane zdarzenie lub w klasie pochodnej. OnEventNamemetoda następnie wywołuje zdarzenie.
Uwaga
Chronione OnEventNamemetoda umożliwia również klas pochodnych zastąpić zdarzenia bez dołączania pełnomocnika do niego.Klasa pochodna musi zawsze używaj wywołania OnEventNamemetoda klasy bazowej, aby zapewnić delegatów zarejestrowane zdarzenie.
Poniższy przykład definiuje OnAlarmEvent metodę, która jest odpowiedzialny za AlarmEvent zdarzenia.
Protected Sub OnAlarmEvent(e As AlarmEventArgs)
RaiseEvent AlarmEvent(Me, e)
End Sub
protected void OnAlarmEvent(AlarmEventArgs e)
{
AlarmEvent(this, e);
}
protected:
void OnAlarmEvent(AlarmEventArgs^ e)
{
AlarmEvent(this, e);
}
Poniższy przykład definiuje metodę o nazwie Set zawierający logiki ognia zdarzenie, wywołując OnAlarmEvent metody. Jeśli godzin i minut czasu alarmu równa godzin i minut bieżący czas Set uruchamia metodę AlarmEventArgs obiektu i dostarcza czas, jaki minął alarmu. Po wykonanie procedury obsługi zdarzeń, sprawdza wartość Snooze właściwości. Jeśli Snooze jest false, zdarzenia alarm nie więcej mają być wywoływane tak Set metody można zakończyć. Jeśli Snooze jest true, czas, alarm jest wyłączyć jest zwiększany o wartość Interval właściwości.
Public Sub [Set]()
Do
System.Threading.Thread.Sleep(2000)
Dim currentTime As DateTime = Date.Now
' Test whether it is time for the alarm to go off.
If currentTime.Hour = alarmTime.Hour And _
currentTime.Minute = AlarmTime.Minute Then
Dim args As New AlarmEventArgs(currentTime)
OnAlarmEvent(args)
If args.Snooze = False Then
Exit Sub
Else
Me.alarmTime = Me.alarmTime.AddMinutes(Me.interval)
End If
End If
Loop
End Sub
public void Set()
{
while (true) {
System.Threading.Thread.Sleep(2000);
DateTime currentTime = DateTime.Now;
// Test whether it is time for the alarm to go off.
if (currentTime.Hour == alarmTime.Hour &&
currentTime.Minute == alarmTime.Minute)
{
AlarmEventArgs args = new AlarmEventArgs(currentTime);
OnAlarmEvent(args);
if (! args.Snooze)
return;
else
this.alarmTime = this.alarmTime.AddMinutes(this.interval);
}
}
}
void Set()
{
do {
Thread::Sleep(2000);
System::DateTime^ currentTime = DateTime::Now;
// Test whether it's time for the alarm to go off.
if (currentTime->Hour == alarmTime->Hour && currentTime->Minute == alarmTime->Minute)
{
AlarmEventArgs^ args = gcnew AlarmEventArgs(currentTime);
OnAlarmEvent(args);
if (args->Snooze == false)
return;
else
this->alarmTime = this->alarmTime->AddMinutes(this->interval);
}
} while (true);
}
Poniższy przykład zawiera wszystkie kod źródłowy dla klasy alarmu.
Public Class Alarm
Private alarmTime As Date
Private interval As Integer = 10
Event AlarmEvent As AlarmEventHandler
Public Sub New(time As Date)
Me.New(time, 10)
End Sub
Public Sub New(time As Date, interval As Integer)
Me.alarmTime = time
Me.interval = interval
End Sub
Public Sub [Set]()
Do
System.Threading.Thread.Sleep(2000)
Dim currentTime As DateTime = Date.Now
' Test whether it is time for the alarm to go off.
If currentTime.Hour = alarmTime.Hour And _
currentTime.Minute = AlarmTime.Minute Then
Dim args As New AlarmEventArgs(currentTime)
OnAlarmEvent(args)
If args.Snooze = False Then
Exit Sub
Else
Me.alarmTime = Me.alarmTime.AddMinutes(Me.interval)
End If
End If
Loop
End Sub
Protected Sub OnAlarmEvent(e As AlarmEventArgs)
RaiseEvent AlarmEvent(Me, e)
End Sub
End Class
public class Alarm
{
private DateTime alarmTime;
private int interval = 10;
public event AlarmEventHandler AlarmEvent;
public Alarm(DateTime time) : this(time, 10)
{
}
public Alarm(DateTime time, int interval)
{
this.alarmTime = time;
this.interval = interval;
}
public void Set()
{
while (true) {
System.Threading.Thread.Sleep(2000);
DateTime currentTime = DateTime.Now;
// Test whether it is time for the alarm to go off.
if (currentTime.Hour == alarmTime.Hour &&
currentTime.Minute == alarmTime.Minute)
{
AlarmEventArgs args = new AlarmEventArgs(currentTime);
OnAlarmEvent(args);
if (! args.Snooze)
return;
else
this.alarmTime = this.alarmTime.AddMinutes(this.interval);
}
}
}
protected void OnAlarmEvent(AlarmEventArgs e)
{
AlarmEvent(this, e);
}
}
public ref class Alarm
{
private:
System::DateTime^ alarmTime;
int interval;
public:
event AlarmEventHandler^ AlarmEvent;
Alarm(System::DateTime^ time) : alarmTime(time), interval(10) { };
Alarm(System::DateTime^ time, int interval) : alarmTime(time), interval(interval) {};
void Set()
{
do {
Thread::Sleep(2000);
System::DateTime^ currentTime = DateTime::Now;
// Test whether it's time for the alarm to go off.
if (currentTime->Hour == alarmTime->Hour && currentTime->Minute == alarmTime->Minute)
{
AlarmEventArgs^ args = gcnew AlarmEventArgs(currentTime);
OnAlarmEvent(args);
if (args->Snooze == false)
return;
else
this->alarmTime = this->alarmTime->AddMinutes(this->interval);
}
} while (true);
}
protected:
void OnAlarmEvent(AlarmEventArgs^ e)
{
AlarmEvent(this, e);
}
};
Zobacz też
Zadania
Jak: podnoszenie i zużywają zdarzeń
Jak: wdrożenie zdarzenia w klasie