رفع حدث
إذا كنت ترغب أن تقوم فئتك برفع حدث ما، يجب عليك توفير العناصر الثلاثة التالية:
فئة توفر بيانات الحدث.
مفوض الحدث.
الفئة التي ترفع الحدث.
تعريف فئة لتوفير بيانات الأحداث
بواسطة الاصطلاح في .NET Framework، عندما يتم رفع حدث، فسيمرر بيانات الحدث إلي معالجات الحدث الخاصة به. بيانات الحدث المتوفرة بواسطة الفئة System.EventArgs أو بواسطة الفئة المشتقة منها.
غالباً لا يحتوي الحدث علي بيانات مخصصة; حقيقة أن الحدث الذي تم تشغيله يوفر كافة المعلومات التي تتطلبها معالجات الأحداث. في هذه الحالة، يمكن تمرير الحدث خلال الكائن EventArgs إلي المعالجات الخاصة به. تحتوي الفئة EventArgsعلي عضو واحد فقط، Empty، وهو غير موروث من System.Object. يمكن استخدامه لإنشاء مثيل جديد للفئة EventArgs.
إذا لم يكن للحدث أي بيانات مخصصة، فيمكنه تمرير مثيل الفئة المشتقة من EventArgs إلى معالجات الحدث. استناداً إلى دقة البيانات التي يمررها الحدث إلى المعالجات، قد تتمكن من استخدام فئة بيانات حدث موجودة مسبقاً في .NET Framework. على سبيل المثال، إذا كان معالج الأحداث يسمح بأن يتم إلغاء الإجراء المقترن مع الحدث، يمكنك استخدام الفئة CancelEventArgs.
عندما تحتاج إلى توفير بيانات مخصصة إلى المعالجات و فئة موجودة مسبقاً وتكون غير متوفرة، يمكنك تعريف فئة الحدث الخاص بك. يجب اشتقاقها من System.EventArgs. بواسطة الاصطلاح ، تسمى هذه الفئة بـ EventNameEventArgs. يوضح المثال التالي مثل تلك فئة الحدث المخصص. ويعرف فئة باسم AlarmEventArgs والتي توفر عنصرين بيانات إلي معالجات الأحداث: الخاصية Time وهي للقراءة فقط، التي تشير إلى وقت إيقاف الإنذار; و الخاصية Snooze، والتي تشير إلى ما إذا كان يجب يجب إطلاق الإنذار مرة أخرى بعد فاصل زمني معيّن أو ما إذا كان يجب إلغاء الإنذارات المستقبلية.
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; }
}
}
تعريف مفوض عن الحدث
يتم استخدام مفوض الحدث لتعريف توقيع الحدث. يتوافق مفوض حدث معين عادةً مع فئة حدث معينة. بواسطة الاصطلاح، الأحداث في .NET Framework يكون لديها التوقيع EventName (sender,e) ، حيث يكون sender هو Object والذي يوفر مرجع فئة أو بنية تقوم بتشغيل الحدث، و يكون e هو الكائن EventArgs أو كائن مشتق من EventArgs والذي يوفر بيانات الحدث. يأخذ عندئذ تعريف المفوض عادةً النموذج EventNameHandler (sender,e).
إذا كنت تستخدم أحد فئات أحداث المعرّفة مسبقاً في مكتبة فئات .NET Framework أو في مكتبة لجهة خارجية، فمن المحتمل أن يتم تعريف مفوض حدث مطابق أيضاً في تلك المكتبة. على سبيل المثال، يمكن استخدام المفوض EventHandler مع الفئة EventArgs. وبشكل مماثل،يمكن استخدام المفوض CancelEventHandler مع الفئة CancelEventArgs.
إذا قمت بتعريف بيانات حدث مخصص، يمكنك أيضاً تعريف مفوض مخصص ليقوم بتعريف توقيع الحدث، أو يمكنك استخدام المفوض العام Action<T1, T2>.
يحدد المثال التالي مفوض حدث تم تسميته بـ AlarmEventHandler.
Public Delegate Sub AlarmEventHandler(sender As Object, e As AlarmEventArgs)
public delegate void AlarmEventHandler(object sender, AlarmEventArgs e);
تعريف فئة لتقوم برفع الحدث
الفئة التي ترفع الحدث يجب أن توفر تعريف الحدث و تعريف أسلوب رفع الحدث. بالإضافة إلى ذلك، فإنه يجب أن توفر بعض المنطق لرفع الحدث في خاصية أو أسلوب الفئة.
قم بتعريف عضو للحدث في الفئة الخاصة بك باستخدام الكلمة الأساسية event في C# أو العبارة Event في Visual Basic. عندما يصادف المحول البرمجي تعريف حدث في الفئة الخاصة بك، فسيقوم بإنشاء عضو خاص مثل:
private EventNameHandler eh = null;
ينشئ المحول البرمجي أيضاً أسلوبين عمومين، هما add_EventName و remove_EventName. هذان الأسلوبان هما توصيلات للحدث و التي تسمح بأن يتم دمج أو إزالة المفوضين من مفوض الحدث eh. يتم إخفاء التفاصيل عن المبرمج.
ملاحظة |
---|
في اللغات الأخرى غير C# و Visual Basic 2005، قد لا يقوم المحول البرمجي تلقائياً بإنشاء التعليمة البرمجية مقابلة لعضو الحدث، وقد يجب عليك تعريف توصيلات الحدث وحقل مفوض خاص بشكل واضح. |
يقوم المثال التالي بتعريف حدث باسم AlarmEvent. هي مأخوذة من المثال للفئة المُسماه بـ Alarm والموضحة تعليمتها البرمجية المصدرية أدناه. لاحظ أنه لديه التوقيع للمفوض AlarmEventHandler.
Event AlarmEvent As AlarmEventHandler
public event AlarmEventHandler AlarmEvent;
حالما تنتهي من تعريف تطبيق الحدث، فيجب عليك تحديد متى يتم رفع الحدث. قم برفع الحدث بواسطة استدعاء الأسلوب المحمية OnEventName في الفئة التي عرفت الحدث، أو في الفئة المشتقة. يقوم عندئذ الأسلوب OnEventName برفع الحدث.
ملاحظة |
---|
يسمح أيضا الأسلوب المحمي OnEventName للفئات المشتقة بتجاوز الحدث دون إرفاق مفوض له.يجب أن تقوم الفئة المشتقة دائماً باستدعاء الأسلوب OnEventName من الفئة الأساسية للتأكد من أن استلام المفوضين المسجلين للحدث. |
يعرّف المثال التالي الأسلوب OnAlarmEvent، وهو المسؤل عن رفع الحدث AlarmEvent.
Protected Sub OnAlarmEvent(e As AlarmEventArgs)
RaiseEvent AlarmEvent(Me, e)
End Sub
protected void OnAlarmEvent(AlarmEventArgs e)
{
AlarmEvent(this, e);
}
يعرّف المثال التالي الأسلوب المسماه Set و التي تحتوي على المعلومات المنطقية لإطلاق الحدث عن طريق استدعاء الأسلوب OnAlarmEvent. إذا كان عدد الساعات والدقائق الخاصة بوقت الإنذار تساوي الساعات والدقائق للوقت الحالي، فسيقوم الأسلوب Set بإنشاء مثيل الكائن AlarmEventArgs كما يوفر له الوقت الذي توقف فيه الإنذار. بعد تنفيذ معالجات الأحداث، فستقوم بفحص قيمة الخاصية Snooze. إذا كانت Snooze هي false، فلن يكون يتم إطلاق أية أحداث إنذار، لذلك يمكن للأسلوب Set أن ينتهي. إذا كانت Snooze هي true، فسيتم زيادة الوقت الذي سيتوقف فيه الإنذار بمقدار قيمة الخاصية Interval.
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);
}
}
}
يتضمن المثال التالي كافة التعليمات البرمجية المصدر لفئة الإنذار.
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);
}
}
راجع أيضًا:
المهام
كيفية القيام بما يلي: إطلاق و استهلاك الأحداث
كيفية القيام بما يلي: تنفيذ الأحداث في الفئة الخاصة بك