مشاركة عبر


نظرة عامة حول الأحداث الموجهة

يصف هذا الموضوع مفهوم الأحداث الموجهة في Windows Presentation Foundation (WPF). يعرّف هذا الموضوع مصطلحات الأحداث الموجهة, يصف كيف يتم توجيه الأحداث الموجهة عبر شجرة عناصر, يلخص كيفية معالجة الأحداث الموجهة و يتناول كيفية إنشاء الأحداث الموجهة المخصصة الخاصة بك. 

يشتمل هذا الموضوع على الأقسام التالية.

  • المتطلبات الأساسية
  • ما هو الحدث الموجه ؟
  • استراتيجيات التوجيه
  • سبب استخدام الأحداث الموجهة؟
  • إضافة و تنفيذ معالج حدث للأحداث الموجه
  • معالجات الفئة
  • الأحداث المرفقة في WPF
  • أسماء الحدث الموجهة في XAML
  • أحداث إدخال WPF
  • EventSetters و EventTriggers
  • المزيد حول الأحداث الموجهة
  • موضوعات ذات صلة

المتطلبات الأساسية

يفترض هذا الموضوع أن يكون لديك معرفة أساسية ب وقت تشغيل اللغة العامة (CLR) و البرمجة الموجهة للكائن , أيضاً مفهوم كيف أن العلاقات بين عناصر WPF يمكن أن تكون conceptualized كشجرة. لمتابعة الأمثلة في هذا الموضوع يجب أيضاً فهم Extensible Application Markup Language (XAML) و معرفة كيفية كتابة تطبيقات WPF أساسية أو صفحات. للمزيد من المعلومات، راجع الشروع في استخدام WPF ونظرة عامة على XAML (WPF).

ما هو الحدث الموجه ؟

يمكنك التفكير في الأحداث الموجهة إما من منظور الوظيفة أو التطبيق. يتم تقديم كلا التعريفين هنا، لأن بعض الأشخاص يجدوا تعريف أو أخر مفيد أكثر.

التعريف الوظيفي: الحدث الموجّه هو نوع حدث الذي يمكنه استدعاء معالجات على مستمعين عدة في شجرة العنصر، وليس فقط على الكائن الذي يظهر الحدث.

تعريف التطبيق: الحدث الموجه هو حدث CLR الذي تم نسخه بواسطة مثيل من فئة RoutedEvent و تمت معالجته بواسطة نظام حدث Windows Presentation Foundation (WPF).

تطبيق WPF نموذجي يحتوي على العديد من العناصر. ما إذا كان تم إنشاؤها في التعليمات البرمجية أو تم تعريفها في XAML، هذه العناصر موجودة في علاقة شجرة العنصر ببعضها البعض. يمكن لمسار الحدث السفر في أحد الاتجاهين اعتماداً على تعريف الحدث و لكن بشكل عام ينتقل المسار من عنصر المصدر و من ثم يسير بشكل فقاعي إلى أعلى خلال شجرة العنصر حتى يصل إلى جذر شجرة العنصر (عادةً صفحة أو إطار). قد يكون مفهوم الفقاعي مألوفاً لك إذا كنت قد عملت مع طراز كائن DHTML مسبقاً.

خذ بعين الاعتبار شجرة العنصر البسيطة التالية:

<Border Height="50" Width="300" BorderBrush="Gray" BorderThickness="1">
  <StackPanel Background="LightGray" Orientation="Horizontal" Button.Click="CommonClickHandler">
    <Button Name="YesButton" Width="Auto" >Yes</Button>
    <Button Name="NoButton" Width="Auto" >No</Button>
    <Button Name="CancelButton" Width="Auto" >Cancel</Button>
  </StackPanel>
</Border>

ينتج عن شجرة العنصر هذه شيء كما يلي:

الأزرار "نعم"، و"لا" و"إلغاء الأمر"

في شجرة العنصر المبسطة, المصدر لحدث Click هو أحد عناصر Button و أيهما Button تم النقر فوقه هو العنصر الأول الذي يحتوي على الفرصة لمعالجة الحدث. و لكن إذ لم يوجد أي معالج مرفق إلى Button الذي يعمل على الحدث، إذا الحدث سوف يسير بشكل فقاعي لأعلى إلى أصل Button في شجرة العنصر، و الذي هو StackPanel. الحدث قد يسير بشكل فقاعي إلى Border ، و من ثم بعد جذر الصفحة من شجرة العنصر (غير معروض).

بمعنى آخر، توجيه الحدث من أجل حدث Click هو:

Button--> StackPanel--> Border-->...

سيناريوهات المستوى الأعلى للأحداث الموجهة

التالي هو ملخص مختصر من السيناريوهات التي تحفز مفهوم الحدث الموجّه، و سبب أن حدث CLR النموذجي غير ملائمة لهذه السيناريوهات:

تكوين عنصر التحكم و التغليف: عناصر التحكم المتنوعة في WPF تحتوي على طراز محتوى غني. على سبيل المثال، يمكنك وضع صورة داخل Button، الذي يمد بفاعلية الشجرة المرئية للزر. مع ذلك، يجب ألا تقطع الصورة المضافة سلوك اختبار التوصل الذي يؤدي إلى أن الزر يستجيب إلى Click من المحتوى الخاص به, حتى و إن لم ينقر المستخدم فوق وحدات البكسل التي هي تقنياً جزء من الصورة.

نقاط مرفق المعالج المفرد: في Windows Forms، يجب عليك أن تقوم بإرفاق نفس المعالج عدة مرات لمعالجة الأحداث التي يمكن رفعها من عدة عناصر. الأحداث الموجهة تتيح لك إرفاق هذا المعالج مرة واحدة فقط، كما هو موضح في المثال السابق, و استخدام منطق المعالج لتحديد من حيث تأتي الحدث إذا لزم الأمر. على سبيل المثال، هذا قد يكون المعالج لXAML المعروض سابقاً:

      Private Sub CommonClickHandler(ByVal sender As Object, ByVal e As RoutedEventArgs)
        Dim feSource As FrameworkElement = TryCast(e.Source, FrameworkElement)
        Select Case feSource.Name
          Case "YesButton"
            ' do something here ...
          Case "NoButton"
            ' do something ...
          Case "CancelButton"
            ' do something ...
        End Select
        e.Handled=True
      End Sub
private void CommonClickHandler(object sender, RoutedEventArgs e)
{
  FrameworkElement feSource = e.Source as FrameworkElement;
  switch (feSource.Name)
  {
    case "YesButton":
      // do something here ...
      break;
    case "NoButton":
      // do something ...
      break;
    case "CancelButton":
      // do something ...
      break;
  }
  e.Handled=true;
}

معالجة الفئة: الأحداث الموجهة تسمح بمعالج ثابت المعرف بواسطة الفئة. معالج الفئة لديه الفرصة لمعالجة الحدث قبل أي معالجات مثيل مرفقة.

إنشاء مرجع إلى حدث دون انعكاس: تتطلب بعض التعليمات البرمجية و تقنيات العلامات طريقة لتعريف حدث معين. يقوم الحدث الموجه بإنشاء حقل RoutedEvent كمعرّف، و الذي يوفر تقنية تعريف حدث قوة لا يتطلب انعكاس ثابت أو وقت التشغيل.

كيفية يتم التنفيذ الأحداث الموجه

الحدث الموجه هو حدث CLR الذي تم نسخه بواسطة مثيل من فئة RoutedEvent و تم تسجيله مع نظام حدث WPF. مثيل RoutedEvent الذي تم الحصول عليه من التسجيل عادة يحتفظ به كعضو حقل public static readonly من الفئة التي تسجل و بالتالي "تملك" الحدث الموجه. الاتصال إلى حدث CLR المسمى بتماثل (التي يتم أحياناً تعريفه كحدث برنامج تضمين) يتم تحقيقه من قبل تجاوز تطبيقات add و remove للحدث CLR. عادةً, add و remove تترك كافتراضي ضمني الذي يستخدم بناء جملة الحدث محدد اللغة المناسبة من أجل إضافة و إزالة المعالجات لهذا الحدث. نسخ الحدث الموجه و آلية الاتصال تشبه بصورة تصورية كيف أن الخاصية التبعية هي خاصية CLR الذي يتم نسخها بواسطة فئة DependencyProperty و تسجيلها مع نظام خاصية WPF.

يُظهر المثال التالي تعريف الحدث الموجه Tap, بما في ذلك التسجيل و كشف حقل المعرف RoutedEvent و تطبيقات add و remove لحدث Tap CLR.

Public Shared ReadOnly TapEvent As RoutedEvent = EventManager.RegisterRoutedEvent("Tap", RoutingStrategy.Bubble, GetType(RoutedEventHandler), GetType(MyButtonSimple))

' Provide CLR accessors for the event
Public Custom Event Tap As RoutedEventHandler
    AddHandler(ByVal value As RoutedEventHandler)
        Me.AddHandler(TapEvent, value)
    End AddHandler

    RemoveHandler(ByVal value As RoutedEventHandler)
        Me.RemoveHandler(TapEvent, value)
    End RemoveHandler

    RaiseEvent(ByVal sender As Object, ByVal e As RoutedEventArgs)
        Me.RaiseEvent(e)
    End RaiseEvent
End Event
public static readonly RoutedEvent TapEvent = EventManager.RegisterRoutedEvent(
    "Tap", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MyButtonSimple));

// Provide CLR accessors for the event
public event RoutedEventHandler Tap
{
        add { AddHandler(TapEvent, value); } 
        remove { RemoveHandler(TapEvent, value); }
}

معالجات الأحداث الموجهة و XAML

لإضافة معالج لحدث باستخدام XAML, تقوم بتعريف اسم الحدث كسمة على العنصر الموجود في وحدة إصغاء الحدث. قيمة السمة هي اسم أسلوب المعالج المطبق الخاص بك الذي يجب أن يكون موجوداً في الفئة الجزئية من ملف التعليمات البرمجية الخلفية.

<Button Click="b1SetColor">button</Button>

بناء الجملة XAML من أجل إضافة معالجات حدث CLR القياسي هي نفسها من أجل إضافة معالجات الحدث الموجه لأنك في الحقيقة تقوم بإضافة معالجات إلى برنامج تضمين حدث CLR الذي يحتوي أسفله على تطبيق الحدث موجه. للحصول على مزيد من المعلومات حول إضافة معالجات أحداث في XAML، راجع نظرة عامة على XAML (WPF).

استراتيجيات التوجيه

الأحداث الموجهة تستخدم إحدى ثلاث استراتيجيات التوجيه الآتية :

  • الفقاعي: معالجات الأحداث على مصدر الحدث يتم استدعائه. الحدث الموجهة بعد ذلك يتوجه إلى عناصر الأصل المتتابعة حتى الوصول إلى جذر شجرة العنصر. معظم الأحداث الموجهة تستخدم استراتيجية التوجيه الفقاعي. الأحداث الموجهة الفقاعية تستخدم بشكل عام لتقرير الإدخال أو تغييرات الحالة من عناصر تحكم مميزة أو عناصر أخرى لواجهة المستخدم.

  • مباشر: فقط عنصر المصدر نفسه هو المعطى الفرصة لاستدعاء المعالجات في الاستجابة. يماثل هذا التوجيه الذي Windows Forms يستخدمه من أجل الأحداث. مع ذلك، بخلاف حدث CLR القياسي، الأحداث الموجهة المباشرة تدعم معالجة الفئة (معالجة الفئة مفسّرة في المقطع القادم) و يمكن استخدامها بواسطة EventSetter و EventTrigger.

  • **النفق:**في بادئ الأمر، يتم استدعاء معالجات الحدث عند جذر شجرة العنصر. الحدث الموجّه بعد ذلك ينتقل خلال العناصر التابعة المتتابعة طول المسار باتجاه عنصر العقدة الذي هو مصدر الحدث الموجّه (عنصر الذي رفع الحدث الموجّه). أحداث النفق الموجهة عادة ما تستخدم أو تعالج كجزء من تكوين عنصر تحكم، بحيث الأحداث من الأجزاء المركبة يمكن عن عمد منعها أو استبدالها بالأحداث الخاصة إلى عنصر التحكم الكامل. أحداث الإدخال المتوفرة في WPF غالباً ما تأتي مطبقة مثل زوج النفق/الفقاعي. يتم أيضاً في بعض الأحيان الإشارة إلى أحداث النفق كأحداث المعاينة بسبب اصطلاح تسمية المستخدم للأزواج.

سبب استخدام الأحداث الموجهة؟

كمطور تطبيق, لا تحتاج دوماً أن تعرف أو أن يهمك إذا كان الحدث الذي تقوم بمعالجته مطبّق كحدث موجه. الأحداث الموجهة لها سلوك خاص, لكن هذا السلوك غير مرئي بشكل كبير إذا كنت ستعالج حدث على العنصر حيث تم رفعه.

حيث تصبح الأحداث الموجهة فعالة إذا كنت تستخدم أي من السيناريوهات المقترحة: تعريف معالجات شائعة عند جذر شائع, تكوين عنصر التحكم الخاص بك, أو تعريف فئة عنصر تحكم مخصص الخاص بك.

لا يحتاج مستمعي الأحداث الموجهة و مصادر الأحداث الموجهة إلى مشاركة حدث شائع في التسلسل الهرمي الخاص بها. أي UIElement أو ContentElement يمكن أن يكون مستمع حدث لأي حدث موجه. لذلك، يمكنك استخدام مجموعة كاملة من الأحداث الموجهة المتوفرة من خلال مجموعة عمل API كواجهة أساسية حيث العناصر المتباينة في التطبيق يمكنها تبادل معلومات الحدث. مفهوم "الواجهة" للأحداث الموجهة يكون قابل للتطبيق بشكل لأحداث الإدخال.

يمكن أن تستخدم الأحداث الموجهة أيضاً للاتصال من خلال شجرة العنصر لأن بيانات الحدث للحدث يتم تحويلها إلى كل عنصر في المسار. يمكن لعنصر واحد تغيير شيء ما في بيانات الحدث، و هذا التغيير قد يكون متوفراً إلى العنصر التالي في المسار.

بالإضافة إلى وجه التوجيه ، هناك سببين أن أي حدث WPF معطى قد يتم تطبيقه كحدث موجه بدلاً من حدث CLR القياسي. إذا كنت تقوم بتنفيذ الأحداث الخاصة بك, فعليك أيضاً مراعاة هذه المبادئ:

  • ميزات قولبة و تنميط WPF معينة مثل EventSetter و EventTrigger تتطلب الحدث المشار إليه أن يكون حدث موجه. هذا هو سيناريو معرّف الحدث الذي تم ذكره مسبقًا.

  • تدعم الأحداث الموجهة آلية معالجة الفئة حيث فيه يمكن للفئة تحديد أساليب ثابتة التي تكون لديها الفرصة لمعالجة الأحداث الموجهة قبل أن يمكن لأي معالجات مثيل مسجلة الوصول اليهم. و هذا مفيد جداً في تصميم التحكم لأن الفئة الخاصة بك يمكنها فرض سلوكيات فئة تستند إلى الحدث التي لا يمكن منعها بطريق الخطأ بواسطة معالجة الحدث على المثيل.

كل من الاعتبارات أعلاه تمت مناقشتها في مقطع مستقل من هذا الموضوع.

إضافة و تنفيذ معالج حدث للأحداث الموجه

لإضافة معالج حدث في XAML، يمكنك ببساطة إضافة اسم الحدث إلى عنصر كسمة و تعيين قيمة السمة مثل اسم معالج الحدث الذي يقوم بتنفيذ مفوض مناسب كما في المثال التالي.

<Button Click="b1SetColor">button</Button>

b1SetColor هو اسم معالج مطبقة يحتوي على تعليمات برمجية التي تعالجClickحدث. b1SetColor يجب أن يكون لديك نفس توقيعRoutedEventHandlerالمفوض، وهو المفوض معالج حدثClickحدث. المعلمة الأولى لكافة تفويضات معالج الحدث الموجه تعيّن العنصر الذي يتم إضافة معالج الحدث إليه و تقوم المعلمة الثانية بتحديد البيانات للحدث.

      Private Sub b1SetColor(ByVal sender As Object, ByVal args As RoutedEventArgs)
        'logic to handle the Click event


...


      End Sub
void b1SetColor(object sender, RoutedEventArgs args)
{
  //logic to handle the Click event


...


}

RoutedEventHandler هو تفويض معالج الحدث الموجه الأساسي. بالنسبة للأحداث الموجهة التخصصية لعناصر التحكم أو السيناريوهات المعينة, المفوضين المستخدمين لمعالجات الأحداث الموجهة أيضاً قد تصبح أكثر تخصصية ، بحيث يمكن إرسال بيانات حدث متخصص. على سبيل المثال، في سيناريو إدخال شائع, يمكنك معالجة حدث DragEnter الموجه. يجب تنفيذ على المعالج الخاص بك تنفيذ مفوض DragEventHandler. باستخدام المفوض الأكثر خصوصية, يمكنك معالجة DragEventArgs في المعالج و قراءة خاصية Data، التي تحتوي على حمولة الحافظة من عملية السحب.

لمثال كامل عن كيفية إضافة معالج حدث إلى عنصر باستخدام XAML, راجع كيفية القيام بما يلي: معالجة حدث موجًّه‬.

إضافة معالج للحدث الموجّه في التطبيق الذي تم إنشاؤه في التعليمات البرمجية هي طريقة مباشرة. يمكن دوماً أن يتم إضافة معالجات الحدث الموجه من خلال أسلوب مساعد AddHandler (و هو نفس الأسلوب الذي تستدعيه النسخ الموجودة من أجل add.) مع ذلك، الأحداث الموجهة WPF الموجودة لديها بشكل عام تطبيقات نسخ من منطق add و remove الذي يسمح لمعالجات الأحداث الموجهة أن تضاف من قبل بناء جملة الحدث الخاص بلغة معينة و الذي هو بناء جملة بديهي أكثر من أسلوب المساعد. التالي هو مثال لاستخدام الأسلوب المساعد:

       Private Sub MakeButton()
            Dim b2 As New Button()
            b2.AddHandler(Button.ClickEvent, New RoutedEventHandler(AddressOf Onb2Click))
       End Sub
        Private Sub Onb2Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
            'logic to handle the Click event     
        End Sub
void MakeButton()
 {
     Button b2 = new Button();
     b2.AddHandler(Button.ClickEvent, new RoutedEventHandler(Onb2Click));
 }
 void Onb2Click(object sender, RoutedEventArgs e)
 {
     //logic to handle the Click event     
 }

يظهر المثال التالي بناء جملة عامل التشغيل #C ( Visual Basic يحتوي على بناء جملة عامل تشغيل مختلف قليلاً بسبب معالجته لإلغاء المرجعية):

        Private Sub MakeButton2()
          Dim b2 As New Button()
          AddHandler b2.Click, AddressOf Onb2Click2
        End Sub
        Private Sub Onb2Click2(ByVal sender As Object, ByVal e As RoutedEventArgs)
          'logic to handle the Click event     
        End Sub
void MakeButton2()
{
  Button b2 = new Button();
  b2.Click += new RoutedEventHandler(Onb2Click2);
}
void Onb2Click2(object sender, RoutedEventArgs e)
{
  //logic to handle the Click event     
}

للحصول على مثال عن كيفية إضافة معالج الحدث في التعليمات البرمجية، راجع كيفية القيام بما يلي: إضافة معالج أحداث باستخدام رمز.

إذا كنت تستخدم Visual Basic، يمكنك أيضاً استخدام الكلمة الأساسية Handles لإضافة معالجات كجزء من تعريفات المعالج. لمزيد من المعلومات، راجع Visual Basic و معالجة حدث WPF.

مفهوم المُعالَج

تشترك الجميع توجيه الأحداث شائعة حدث بيانات فئة أساسية، RoutedEventArgs. RoutedEventArgsتعرفHandledخاصية، الذي يأخذ القيمة منطقية. الغرض من خاصية Handled هو تمكين أي معالج حدث بطول المسار لوضع علامة على الحدث الموجه كمُعالَج، بواسطة تعيين القيمة من Handled إلى true. بعد المعالجة بواسطة المعالج عند عنصر واحد طول المسار, بيانات الحدث المشتركة يتم الإبلاغ عنها مرة أخرى إلى كل مستمع طول المسار.

القيمة من Handled تؤثر على كيف يتم الإبلاغ عن و معالجة الحدث الموجّه أثناء انتقالها على طول المسار. إذا كان Handled هو true في بيانات الحدث للحدث الموجه, فالمعالجات التي تسمع ذلك الحدث الموجه على عناصر أخرى لا يتم بشكل عام استدعائه لهذا المثيل للحدث المعين. يكون هذا صحيحاً لكل من المعالجات المرفقة في XAML و المعالجات المضافة بواسطة بُنى جمل مرفق معالج الحدث بلغة معينة مثل += أو Handles. لسيناريوهات المعالج الأكثر شيوعاً, وضع علامة على الحدث كمُعالَج بواسطة تعيين Handled إلى true سيقوم بوقف التوجيه لتوجيه النفق أو توجيه الفقاعي و أيضاً لأي حدث يتم معالجته عند نقطة في المسار من قبل معالج الفئة.

مع ذلك، توجد آلية "handledEventsToo" فيه يمكن للمستمعين الاستمرار بتشغيل المعالجات استجابةً إلى الأحداث الموجهة حيث Handled هو true في بيانات الحدث. بمعنى آخر، الحدث الموجه لا يتم توقيفه حقاً عن طريق وضع علامة على بيانات حدث كمُعالَجة. يمكنك فقط استخدام آلية handledEventsToo في التعليمات البرمجية أو في EventSetter:

  • في التعليمات البرمجية بدلاً من استخدام بناء جملة حدث بلغة معينة الذي يعمل لأحداث CLR العامة، قم باستدعاء أسلوب WPFAddHandler(RoutedEvent, Delegate, Boolean) لإضافة المعالج الخاص بك. حدد القيمة من handledEventsToo كـ true.

  • في EventSetter ، قم بتعيين سمة HandledEventsToo لتكون true.

بالإضافة إلى السلوك الذي ينتج عن حالة Handled في الأحداث الموجهة, مفهوم Handled له تبعاته لكيف يجب أن تقوم بتصميم التطبيق الخاص بك و كتابة تعليمات برمجية معالج الحدث. يمكن conceptualize Handled كأنه بروتوكول بسيط يكشف بواسطة الأحداث الموجهة. بالضبط كيفية استخدام هذا البروتوكول يرجع إليك و لكن التصميم الأساسي لطريقة استخدام قيمة Handled يكون كالتالي:

  • إذا تم وضع علامة على حدث موجه كمُعالَج فهو لا يحتاج إلى المعالجة مرة أخرى بواسطة عناصر أخرى على هذا الطريق.

  • إذا لم يتم وضع علامة على حدث موجه كمُعالَج, فان المستمعين الأخرين الذين كانوا مسبقاً على المسار قد اختاروا إما عدم تسجيل معالج أو المعالجات التي تم تسجيلها اختارت ألا تعالج بيانات الحدث و تعيين Handled إلى true. (أو هو بالتأكيد من المحتمل أن المستمع الحالي هو النقطة الأولى في المسار.) المعالجات على المستمع الحالي الآن لديه ثلاثة اتجاهات ممكن للإجراء:

    • لا يتم اتخاذ أي إجراء; يبقى الحدث غير معالج و يتوجه الحدث إلى المستمع التالي.

    • تنفيذ التعليمات البرمجية في استجابة إلى الحدث و لكن تأكد من أن الإجراء المتخذ ليس كثير كفاية لضمان وضع علامة على الحدث كمُعالَج. يتم توجيه الحدث إلى وحدة الإصغاء التالية.

    • تنفيذ التعليمات البرمجية استجابة إلى الحدث. ضع علامة على الحدث كمُعالَج في بيانات الحدث التي تم تمريرها إلى المعالج، لأن الإجراء المتخذ يعتبر كافي جداً لضمان وضع علامة كمُعالَج. الحدث سيظل يتوجه إلى المستمع التالي و لكن مع Handled = true في بيانات الحدث الخاصة به، بذلك فقط مستمعين handledEventsToo لديهم الفرصة لاستدعاء معالجات أخرى.

هذا التصميم الأساسي يُدعم بواسطة سلوك التوجيه الذي تم ذكره مسبقًا: انه صعب أكثر (على الرغم من انه ممكن في التعليمات البرمجية أو الأنماط) إرفاق معالجات للأحداث الموجهة التي يتم استدعائها حتى في حالة انه تم تعيين بالفعل معالج سابق طول المسار Handled إلى true.

للمزيد من المعلومات حول Handled, معالجة الفئة للأحداث الموجهة و التوصيات حول عندما يكون مناسب وضع علامة على حدث موجه كHandled, راجع وضع علامة على توجيه الأحداث كمعالجة و معالجة الفئة.

في التطبيقات, من الشائع تماماً معالجة فقط حدث موجه فقاعي على الكائن الذي رفعه و لا تقلق على الصفات المميزة للتوجيه الخاصة بالحدث. مع ذلك، يعد تدريباً جيداً أن تضع علامة على الحدث الموجه كمُعالَج في بيانات الحدث, لمنع الآثار الجانبية غير المتوقعة في حالة أن العنصر الذي يكون في أعلى شجرة العنصر له أيضاً معالج مرفق لنفس الحدث الموجه.

معالجات الفئة

إذا كنت تقوم بتعريف فئة تشتق بطريقة ما من DependencyObject، يمكنك أيضاً تعريف و إرفاق معالج فئة للحدث الموجه الذي يكون عضواً حدث مُعرَف أو موروث من الفئة الخاصة بك. يتم استدعاء معالجات الفئة قبل أية معالج مستمع مثيل متصل إلى مثيل من تلك الفئة عندما يصل الحدث الموجه إلى مثيل عنصر في المسار الخاص به.

بعض عناصر التحكم WPF لديها معالجة فئة موروثة لأحداث موجهة معينة. قد يؤدي ذلك إلى منح مظهر خارجي أن الحدث الموجه لم يتم رفعه, لكن في الحقيقة فإنه يتم معالجة فئته, و من المحتمل أن يكون الحدث الموجه لا يزال يتم معالجته بواسطة معالجات المثيل الخاصة بك إذا استخدمت بعض التقنيات المعينة. أيضاً، العديد من الفئات الأساسية و عناصر التحكم تكشف الأساليب الظاهرية التي يمكن استخدامها لتجاوز سلوك معالجة الفئة. للمزيد من المعلومات حول كلا من كيفية التغلب على معالجة الفئة غير المرغوب فيها و تعريف معالجة الفئة الخاصة بك في فئة مخصصة, راجع وضع علامة على توجيه الأحداث كمعالجة و معالجة الفئة.

الأحداث المرفقة في WPF

لغة XAML تعرّف أيضاً نوع خاص من الحدث يسمى الحدث المرفق . الحدث المرفق يمكنك من إضافة معالج لحدث معين إلى عنصر إجباري. العنصر الذي يعالج الحدث لا يحتاج إلى تعريف أو أن يرث الحدث المرفق كما أن الكائن الذي من المحتمل أن يكون رفع الحدث و الوجهة المعالجة إلى المثيل لا يجب أن يُعرِفوا أو يملكوا ذلك الحدث كعضو فئة.

نظام إدخال WPF يستخدم الأحداث المرفقة بشكل مكثف. مع ذلك، تقريباً كافة هذه الأحداث المرفقة يتم إعادة توجيها خلال عناصر الأساس. ثم تظهر أحداث الإدخال كأحداث موجهة غير مرفقة مكافئة و هم أعضاء من فئة عنصر الأساس. على سبيل المثال، حدث Mouse.MouseDown المرفق الأساسي يمكن معالجته بسهولة أكثر على أي UIElement معطي باستخدام MouseDown على UIElement بدلاً من التعامل مع بناء جملة الحدث المرفق إما في XAML أو التعليمات البرمجية.

للمزيد من المعلومات حول الأحداث المرفقة في WPF, راجع نظرة عامة حول الأحداث المرفقة.

أسماء الحدث الموجهة في XAML

استخدام بناء جملة آخر الذي يشبه typename.بناء جملة الحدث المرفق eventname لكن ليس حصرياً يتكلم عن استخدام الحدث المرفق هو عندما ترفق معالجات للأحداث الموجهة التي يتم رفعها بواسطة عناصر تابعة. تقوم بإرفاق المعالجات إلى أصل مشترك، للاستفادة من توجيه الأحداث على الرغم من أن الأصل المشترك قد لا يكون لديه حدث موجه ذو صلة كعضو. خذ بعين الاعتبار هذا المثال مرة أخرى:

<Border Height="50" Width="300" BorderBrush="Gray" BorderThickness="1">
  <StackPanel Background="LightGray" Orientation="Horizontal" Button.Click="CommonClickHandler">
    <Button Name="YesButton" Width="Auto" >Yes</Button>
    <Button Name="NoButton" Width="Auto" >No</Button>
    <Button Name="CancelButton" Width="Auto" >Cancel</Button>
  </StackPanel>
</Border>

هنا، وحدة إصغاء عنصر الأصل حيث تمت إضافة المعالج هي StackPanel. مع ذلك، فإنه يتم إضافة معالج للحدث الموجه التي تم تعريفه و سيتم رفعه من قبل فئة Button ( في الواقع ButtonBase و لكن متوفر إلى Button خلال الوراثة). Button يملك الحدث و لكن نظام الحدث الموجه تسمح بالمعالجات لأي حدث موجه لإرفاقه إلى أي UIElement أو مستمع مثيل ContentElement الذي يمكنه إرفاق مستمعين لحدث وقت تشغيل اللغة العامة (CLR). مساحة الاسم xmlns الافتراضية لأسماء سمة هذا الحدث المؤهلة هو عادةً مساحة اسم xmlns WPF الافتراضية، و لكن يمكنك أيضاً تحديد مساحات أسماء مسبوقة للأحداث الموجهة المخصصة. لمزيد من المعلومات حول xmlns، راجع مساحات الاسم XAML وتعيين مساحة الاسم ل XAML WPF:

أحداث إدخال WPF

تطبيق متكرر من الأحداث الموجهة داخل النظام الأساسي WPF هو لأحداث الإدخال. في WPF، أسماء أحداث النفق الموجهة تكون مسبوقة بكلمة "معاينة" بواسطة الاصطلاح. أحداث الإدخال غالباً ما تأتي في أزواج، واحد يكون حدث فقاعي و الآخر يكون حدث نفق. على سبيل المثال، حدث KeyDown و حدث PreviewKeyDown يكون لديه نفس التوقيع, مع السابق يكون حدث إدخال فقاعي و الأخير يكون حدث إدخال نفق. من حين لآخر، أحداث الإدخال يكون لديها إصدار فقاعي فقط أو ربما الإصدار توجيه مباشر فقط. في الوثائق، مواضيع الأحداث الموجهة تسند ترافقياً أحداث موجهة مشابهة مع استراتيجيات توجيه بديلة إذا كانت مثل الأحداث موجهة موجودة, و المقاطع في صفحات المرجع المدارة توضح استراتيجية التوجيه لكل حدث موجه.

أحداث الإدخال WPF التي تأتي في أزواج يتم تنفيذها بحيث إجراء مستخدم واحد من الإدخال, مثل الضغط على زر ماوس, سوف يرفع كلا من الأحداث الموجهة للزوج في تسلسل. أولاً ، يتم رفع حدث النفق و ينتقل بالمسار الخاص به. ثم يتم رفع حدث الفقاعي و ينتقل بالمسار الخاص به. الحدثين حرفياً يشاركوا نفس مثيل بيانات الحدث لأن استدعاء أسلوب RaiseEvent في الفئة المطبقة التي ترفع الحدث الفقاعي تستمع إلى بيانات الحدث من حدث النفق و إعادة استخدامه في الحدث الذي تم رفعه جديدأً. المستمعين مع معالجات لحدث النفق تكون لديها الفرصة الأولى لوضع علامة على الحدث الموجه كمُعالَج (معالجات الفئة أولاً، ثم معالجات المثيل). إذا قام عنصر بطول مسار النفق بوضع علامة على الحدث الموجه كمُعالَج، يتم إرسال بيانات الحدث التي تم معالجتها بالفعل على حدث فقاعي و المعالجات النموذجية المرفقة لأحداث الإدخال الفقاعية المكافئة لن يتم استدعائها. للمظهر الخارجي سيكون كأن حدث الفقاعي المعالج لم يتم رفعه. هذا السلوك للمعالجة مفيد من أجل تكوين عنصر التحكم, حيث قد تحتاج إلى كافة أحداث الإدخال المستندة إلى اختبار التوصل أو الأحداث الإدخال المستندة إلى التركيز إلى أن يتم الإبلاغ عنها عن طريق التحكم النهائي بدلاً من الأجزاء المركبة. عنصر التحكم النهائي هو أقرب إلى الجذر في التكوين, و لذلك لديه الفرصة لمعالجة فئة معالجة حدث النفق أولاً ثم ربما تستبدل هذا الحدث الموجه مع حدث محدد التحكم أكثر، كجزء من التعليمات البرمجية التي تقوم بنسخ فئة عنصر التحكم.

كتوضيح لكيفية عمل معالجة حدث الإدخال, خذ بعين الاعتبار مثال حدث الإدخال التالي. في رسم الشجرة التوضيحي التالي، leaf element #2 هو مصدر PreviewMouseDown ثم حدث MouseDown معاً.

نفق و فقاعي حدث الإدخال

الرسم التخطيطي لتوجيه الحدث

ترتيب معالجة الحدث كما يلي:

  1. PreviewMouseDown (نفق) على العنصر الجذر.

  2. PreviewMouseDown (نفق) على العنصر المتوسط # 1.

  3. PreviewMouseDown (نفق) على عنصر المصدر # 2.

  4. MouseDown (فقاعي) على عنصر المصدر # 2.

  5. MouseDown (فقاعي) على العنصر المتوسط # 1.

  6. MouseDown (الفقاعية) على العنصر الجذر.

يوفر مفوض معالج الأحداث الموجهة المراجع إلى كائنين: الكائن الذي يرفع الحدث و الكائن حيث تم استدعاء المعالج. الكائن حيث تم استدعاء المعالج هو الكائن الذي تم الإعلام عنه بواسطة معلمة sender. الكائن حيث تم رفع الحدث أولاً يتم الإعلام عنه بواسطة خاصية Source في بيانات الحدث. الحدث الموجه ما زال يمكن رفعه و معالجته من قبل نفس الكائن, في هذه حالة sender و Source يكونوا متطابقين (هذه هي الحالة مع الخطوات 3 و 4 من قائمة مثال معالجة الحدث).

بسبب النفق و الفقاعي, عناصر الأصل صواب تستقبل أحداث الإدخال حيث Source هو أحد العناصر التابعة الخاصة بهم. عندما يكون هاماً معرفة ما هو عنصر المصدر، يمكنك تحديد عنصر المصدر عن طريق الوصول إلى خاصية Source.

عادةً، بمجرد أن حدث الإدخال يُعلَّم Handled، لا يتم استدعاء معالجات أخرى. بشكل عام، يجب وضع علامة على أحداث الإدخال كمُعالَج بمجرد أن يتم استدعاء معالج الذي يتعامل مع المعالجة المنطقية الخاصة بالتطبيق الخاصة بك من معنى حدث الإدخال.

الاستثناء إلى هذه العبارة العامة حول حالة Handled هي أن معالجات حدث الإدخال التي تم تسجيلها لتجاهل عن عمد حالة Handled من بيانات الحدث لا يزال يمكن استدعائهم بطول المسار. لمزيد من المعلومات، راجع أحداث المعاينة أو وضع علامة على توجيه الأحداث كمعالجة و معالجة الفئة.

طراز بيانات الحدث المشترك بين أحداث النفق و الفقاعي, و تسلسل رفع أحداث النفق الأول ثم الفقاعي, هو ليس مفهوم صحيح بشكل عام لكافة الأحداث الموجهة. هذا السلوك يتم تطبيقه بشكل خاص عن طريق كيف تختار أجهزة إدخال WPF أن ترفع و تتصل أزواج أحداث الإدخال. تنفيذ أحداث الإدخال الخاص بك هو سيناريو متقدم, لكن يمكنك اختيار متابعة هذا الطراز لأحداث الإدخال الخاصة بك أيضاً.

فئات معينة تختار معالجة فئة أحداث إدخال معينة, عادة مع الهدف من إعادة تعريف ما يعني حدث إدخال معين حسب المستخدم داخل عنصر التحكم و رفع حدث جديد. لمزيد من المعلومات، راجع وضع علامة على توجيه الأحداث كمعالجة و معالجة الفئة.

للحصول على مزيد من المعلومات حول الإدخال و كيفية التفاعل الإدخال و الأحداث في سيناريوهات التطبيق النموذجية, راجع نظرة عامة حول المدخلات.

EventSetters و EventTriggers

في الأنماط، يمكنك تضمين بعض بناء جملة معالجة حدث XAML المعرف مسبقاً في العلامات باستخدام EventSetter. عند تطبيق النمط, المعالج المشار إليه يتم إضافته إلى المثيل ذو النمط. يمكنك تعريف EventSetter فقط للحدث الموجّه. فيما يلي مثال. لاحظ أن أسلوب b1SetColor المشار إليه هنا هو في ملف التعليمات البرمجية الخلفية.

<StackPanel
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="SDKSample.EventOvw2"
  Name="dpanel2"
  Initialized="PrimeHandledToo"
>
  <StackPanel.Resources>
    <Style TargetType="{x:Type Button}">
      <EventSetter Event="Click" Handler="b1SetColor"/>
    </Style>
  </StackPanel.Resources>
  <Button>Click me</Button>
  <Button Name="ThisButton" Click="HandleThis">
    Raise event, handle it, use handled=true handler to get it anyway.
  </Button>
</StackPanel>

الميزة المكتسبة هنا هي أن النمط من المحتمل أن يحتوي على قدر كبير من المعلومات الأخرى التي قد تطبق على أي زر في التطبيق الخاص بك و جعل EventSetter أن يكون جزءاً من هذا النمط ترقي إعادة استخدام التعليمات البرمجية حتى في مستوى العلامات. أيضاً، EventSetter تجرد أسماء أسلوب للمعالجات خطوة واحدة إضافية بعيداً عن التطبيق العام و علامات الصفحة.

بناء جملة خاص آخر الذي يضم الحدث الموجه و ميزات الحركة من WPF هو EventTrigger. كما مع EventSetter ، قد يتم استخدام الأحداث الموجهة فقط من أجل EventTrigger. عادةً, يتم تعريف EventTrigger كجزء من أي نمط, لكن EventTrigger يمكن أيضاً أن يتم تعريفه على عناصر مستوى الصفحة كجزء من مجموعة Triggers أو في ControlTemplateEventTrigger يمكنك من تحديد Storyboard الذي يشتغل عندما يصل الحدث الموجه إلى عنصر في المسار الخاص به الذي يقوم بتعريف EventTrigger لهذا الحدث. ميزة EventTrigger عبر فقط معالجة الحدث و التسبب في بدء تشغيل لوحة العمل الموجودة هي أن EventTrigger يوفر أفضل تحكم عبر لوحة العمل و سلوك وقت التشغيل الخاص به. لمزيد من المعلومات، راجع كيفية القيام بما يلي: استخدام مشغلات الحدث للتحكم في لوحة العمل بعد بدئها.

المزيد حول الأحداث الموجهة

يناقش هذا الموضوع بشكل رئيسي الأحداث الموجهة من منظور وصف المفاهيم الأساسية و عرض إرشادات حول كيف و متى يتم الاستجابة إلى الأحداث الموجهة الموجودة مسبقاً في العناصر الأساسية و عناصر التحكم المتنوعة. مع ذلك، يمكنك إنشاء الحدث موجهة الخاص بك على الفئة المخصصة الخاصة بك مع كافة الدعم الضروري مثل فئات بيانات الحدث المتخصص و المفوضين. يمكن أن يكون مالك الحدث الموجه أية فئة و لكن يجب رفع الأحداث الموجهة و معالجتها بواسطة الفئات المشتقة UIElement أو ContentElement حتى يكون مفيداً. للحصول على المزيد من المعلومات عن الأحداث المخصصة، راجع كيفية القيام بما يلي: إنشاء حدث موجه مخصص.

راجع أيضًا:

المرجع

EventManager

RoutedEvent

RoutedEventArgs

المبادئ

وضع علامة على توجيه الأحداث كمعالجة و معالجة الفئة

نظرة عامة حول المدخلات

نظرة عامة على الأوامر

خصائص التبعية المخصصة

الأشجار فى الWPF

أنماط الأحداث ضعيفة