مشاركة عبر


رفع حدث

إذا كنت ترغب أن تقوم فئتك برفع حدث ما، يجب عليك توفير العناصر الثلاثة التالية:

  • فئة توفر بيانات الحدث.

  • مفوض الحدث.

  • الفئة التي ترفع الحدث.

تعريف فئة لتوفير بيانات الأحداث

بواسطة الاصطلاح في .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);
   }  
}

راجع أيضًا:

المهام

كيفية القيام بما يلي: إطلاق و استهلاك الأحداث

كيفية القيام بما يلي: تنفيذ الأحداث في الفئة الخاصة بك

المبادئ

المفوضون والأحداث

موارد أخرى

معالجة ورفع الأحداث