أسبقية قيمة خاصية التبعية

يشرح هذا المقال كيفية العمل لنظام خاصية Windows Presentation Foundation (WPF) يمكن أن يؤثر على قيمة الخاصية التبعية ، و توضح الأسبقية التي عن طريقها أوجه نظام الخاصية يتم تطبيقها إلى القيمة الفعالة للخاصية.

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

  • المتطلبات الأساسية
  • نظام الخاصية WPF
  • الخصائص التبعية قد تكون "معينة" في أماكن متعددة
  • قائمة أسبقية إعداد الخاصية التبعية
  • TemplatedParent
  • خاصية السمة
  • الأنماط (سمة) الافتراضية
  • مراجع و ربط الموارد الحيوية
  • القسرية, الحركات و قيمة الأساس
  • سلوكيات المشغّل
  • ClearValue و قيمة الأسبقية
  • موضوعات ذات صلة

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

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

نظام الخاصية WPF

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

الخصائص التبعية قد تكون "معينة" في أماكن متعددة

التالي هو مثال XAML حيث نفس الخاصية ( Background) تحتوي على ثلاث عمليات "تعيين" مختلفة و التي قد تؤثر على القيمة.

    <Button Background="Red">
      <Button.Style>
        <Style TargetType="{x:Type Button}">
          <Setter Property="Background" Value="Green"/>
          <Style.Triggers>
            <Trigger Property="IsMouseOver" Value="True">
              <Setter Property="Background" Value="Blue" />
            </Trigger>
          </Style.Triggers>
        </Style>
      </Button.Style>
Click
    </Button>

هنا، أي لون كنت تتوقع أن يتم تطبيقه — الأحمر، الأخضر, أو الأزرق؟

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

قائمة أسبقية إعداد الخاصية التبعية

التالي هو الترتيب النهائي الذي يستخدمه نظام الخاصية عند تعيين قيم وقت التشغيل للخصائص التبعية. يتم سرد الأسبقية العليا أولاً. يتم توسيع هذه القائمة على بعض التعميمات التي تمت في نظرة عامة حول خصائص التبعية.

  1. قسرية نظام الخاصية. للحصول على تفاصيل حول القسرية، راجع القسرية، الرسم المتحرك، و قيمة الأساس لاحقًا في هذا الموضوع.

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

  3. القيم المحلية. يتم تعيين القيمة المحلية خلال الملاءمة لخاصية "المجمّع"، والتي يمكن أيضاً أن يتم تعيينها كشكل عنصر سمة أو عنصر الخاصية في XAML، أو بواسطة استدعاء لـ SetValue API باستخدام خاصية لمثيل معين. في حالة تعيين قيمة محلية باستخدام ربط أو مورد، كل هذه تعمل في الأسبقية كما لو تم تعيين قيمة مباشرة.

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

    1. مشغلات من القالب TemplatedParent.

    2. تعيين الخاصية (عادةً خلال سمات XAML) في القالب TemplatedParent.

  5. نمط ضمني. ينطبق فقط على الخاصية Style. الخاصية Style تمتليء بواسطة أي مورد نمط مع المفتاح الذي يتطابق مع نوع هذا العنصر. يجب أن يتواجد مورد النمط هذا إما في الصفحة أو التطبيق; قم بالبحث عن مورد نمط ضمني و الذي لا يتم اتباعه إلى السمات.

  6. نمط المشغلات. المشغلات ضمن أنماط من صفحة أو تطبيق (هذه الأنماط قد تكون واضحة أو ضمنية الأنماط، ولكن ليست من الأنماط الافتراضية، لها الأسبقية الأقل).

  7. قالب المشغلات. أي مشغل من قالب ضمن نمط، أو قالب مطبقة مباشر.

  8. نمط المُعيِّنات. القيم من Setter داخل الأنماط من صفحة أو تطبيق.

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

    1. المشغّلات النشطة في سمة النمط.

    2. المُعيِّنات في نسق النمط.

  10. الوراثة. بعض خصائص التبعية التي تورث قيمها من العنصر الأصل للعناصر التابعة، مثل ذلك الذي لا يحتاج أن يتم تعيينها بشكل خاص على كل عنصر من خلال أحد التطبيقات. للمزيد من التفاصيل ، راجع وراثة قيمة الخاصية.

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

TemplatedParent

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

خاصية السمة

ترتيب البحث الذي تم وصفه من قبل يطبق على كافة الخصائص التبعية الممكنة باستثناء واحدة: الخاصية Style. الخاصية Style تكون فريدة في أنها نفسها لا يكون لها نمط، بحيث لا يتم تطبيق عناصر الأسبقية 5 إلى 8. أيضاً إما تحريك أو إجبار Style فمن غير المستحسن (و الحركات Style تتطلب فئة حركة مخصصة). هذا يترك ثلاث طرق لإمكانية تعيين الخاصية Style:

  • نمط ضمني. الخاصية Style يتم تعيينها إلى خاصية . في معظم السيناريوهات، النمط يكون غير معرف ضمنياً، لكن بدلاً من ذلك يتم كمرجع للمورد بواسطة مفتاح ضمني. في هذه الحالة خاصية النمط نفسها تعمل كما لو كانت قيمة المحلية، عنصر أسبقية 3.

  • نمط ضمني. الخاصية Style لا يتم تعيينها مباشرة. ومع ذلك، يتم إيجاد Style لبعض المستوى في تسلسل بحث المورد (صفحة، تطبيق) وأنه تم ربطه باستخدام مفتاح المورد الذي يتطابق مع نوع النمط الذي سيتم التطبيق عليه. في هذا cكـe Styleيعمل الخصائص نفسها بأسبقية التعرف في التسلسل كـ العنصر 5. يمكن اكتشاف هذه الحالة باستخدام DependencyPropertyHelperضد Styleخاصية و تبحث عن ImplicitStyleReferenceفي نتائج.

  • النمط الافتراضي، والذي يعرف أيضاً باسم سمة النمط. الخاصية Style لم يتم تعيينها مباشرةً، وفي الواقع سيتم قراءتها كـ null حتى وقت التشغيل. في هذه الحالة، يأتي النمط من سمة تقييم وقت التشغيل هو جزء من مشغل العرض التقديمي WPF.

للأنماط الضمنية و التي ليست في السمات، النوع يجب أن يتطابق تماماً — الفئة المشتقة MyButton Button- لا تتضمن استخدام نمط لـButton.

الأنماط (سمة) الافتراضية

كل عنصر تحكم مرفق بـWPF يحتوي على الأنماط الافتراضية. هذا النمط الافتراضي من المحتمل أن يختلف حسب السمة، و لماذا هذا النمط الافتراضي يشار إليه أحياناً كنمط لسمة.

المعلومات الأكثر أهمية موجودة ضمن نمط افتراضي لعنصر التحكم هي قوالب عنصر التحكم الخاصة بها الموجودة في نمط السمة كمُعيِّن للخاصية Template الخاصة به. إذا لم يكن هناك أي قوالب من الأنماط الافتراضية، عنصر تحكم بدون قالب مخصص كجزء من النمط المخصص لن يكون له أي مظهر مرئي على الإطلاق. يعطي القالب من النمط الافتراضي المظهر المرئي لكل عنصر تحكم بنية أساسية، وتقوم أيضاً بتعريف الاتصالات بين الخصائص المعرفة في الشجرة المرئية في القالب و فئة التحكم المطابقة. كل عنصر تحكم يكشف عن مجموعة من الخصائص التي يمكن أن تؤثر على المظهر المرئي لعنصر التحكم بدون استبدال القالب بشكل كامل. على سبيل المثال، ضع في الاعتبار المظهر المرئي الافتراضي لعنصر التحكم Thumb، والذي هو أحد مكونات ScrollBar.

Thumb يحتوي علة خصائص قابلة للتخصيص معينة. القالب الافتراضي لـThumb ينشئ بنية أساسية / شجرة مرئية بمكونات متعددة متداخلة Border لإنشاء مظهر مجسم مشطوف الحواف. إذا كانت الخاصية وهي جزء من القالب تهدف إلى أن يتم كشف تخصيصها بواسطة الفئة Thumb، إذاً هذه الخاصية يجب أن يتم عرضها بواسطة TemplateBinding، داخل القالب. في الحالة Thumb ، تقوم الخصائص المختلفة لهذه الحدود بمشاركة ربط القالب لخصائص مثل Background أو BorderThickness. ولكن بعض الخصائص الأخرى أو الترتيبات المرئية تكون تعليمات برمجية مضمّنة لقالب عنصر التحكم أو منضم إلى القيم التي تأتي مباشرةً من السمة، ولا يمكن تغييرها نقص في استبدال القالب بأكمله. بشكل عام، إذا جاءت الخاصية من الكائن الأصل لتوفير القالب و لا يتم عرضها بواسطة ربط القالب، فإنه لا يمكن ضبطها بواسطة أنماط لأنه لا توجد أية طريقة سهلة لاستهدافه. ولكن الخاصية قد لا تزال تتأثر بخاصية قيمة التوريث في تطبيق القالب أو من قبل القيمة الافتراضية.

تستخدم الأنماط النوع كمفتاح في تعريفاتها. ومع ذلك، عند تطبيق السمات على مثيل عنصر معيّن، تبحث السمات لهذا النوع للتنفيذ عن طريق التحقق من الخاصية DefaultStyleKey على عنصر التحكم. Th هو هو بعكس لاستخدام اكتب حرفي، كما في أنماط الضمني. القيمة DefaultStyleKeyسوف يتوارث المشتقة إلى فئات حتى في حالة عدم تغيير implementer عليه (الطريقة المقصودة لتغيير خاصية هو عدم تجاوزه على المستوى الخصائص، ولكن بدلاً من ذلك تغيير قيمة افتراضية الخاصة بها في خصائص بيانات التعريف). يمكّن هذا indirection من تعريف الفئات الأساسية لتعريف أنماط السمة للعناصر المشتقة التي ليس لها نمط (أو أكثر أهمية، لا تحتوي على قالب داخل ذلك النمط كما وبالتالي لن يكون لها أي مظهر مرئي افتراضي على الإطلاق). وبالتالي، يمكنك اشتقاق MyButton من Button ولا نزال نحصل على القالب الإفتراضي Button. إذا كنت كاتب التحكم في MyButton و أردت سلوك مختلف, قد تتجاوز الخاصية التبعية لبيانات التعريف الخاصة بـ DefaultStyleKey على MyButton لإرجاع مفتاح مختلف، وثم تعريف أنماط السمة ذات الصلة بما في ذلك قالب لـ MyButton التي يجب أن تحزمها مع عنصر التحكم الخاص بك MyButton. للحصول على المزيد من التفاصيل حول السمات, الأنماط و تأليف التحكم, راجع نظرة عامة على تأليف التحكم.

مراجع و ربط الموارد الحيوية

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

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

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

القسرية, الحركات و قيمة الأساس

القسرية و الحركة كليهما تعمل على القيمة التي تم تعريفها كالقيمة الأساسية خلال هذا SDK. القيمة الأساسية هي بالتالي كل قيمة يتم تحديدها من خلال التقييم إلى الأعلى في العناصر حتى يتم الوصول إلى عنصر 2.

للحصول على حركة، القيمة الأساسية يمكن أن يكون لها تأثير على القيمة المتحركة، إذا كانت تلك الحركة لا تحدد كلا من "النموذج"و "إلى" لسلوكيات معينة، أو إذا كانت الحركة عن عمد ترجع إلى القيمة الأساسية عند الإتمام. لمشاهدة ذلك في التدريب العملي، قم بتشغيل النموذج ، من، و‏‫ هدف نموذج قيم الحركة . حاول تعيين القيم المحلية ارتفاع المستطيل في المثال، بحيث تختلف القيمة الأولية المحلية عن أي "نموذج" في الحركة. سيتم ملاحظة أن بدء الحركة مباشرة باستخدام قيم "النموذج" واستبدال القيمة الأساسية عند بدء التشغيل. قد تحدد الحركة العودة للقيم الموجودة قبل الحركة بمجرد إكمال تحديد الإيقاف FillBehavior. فيما بعد, يتم استخدام الأسبقية العادية لتحديد القيمة الأساسية.

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

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

سلوكيات المشغّل

تقوم عناصر التحكم غالباً بتحديد سلوكيات المشغّل المعرفة كجزء من النمط الافتراضي الخاص بها في السمات. تعيين الخصائص المحلية على عناصر التحكم قد يمنع المشغّلات من إمكانية الاستجابة لأحداث تعتمد علي المستخدم إما بشكل مرئي أو سلوكي. الاستخدام الأكثر شيوعاً من مشغل الخصائص هو التحكم في أو ذكر الخصائص مثل IsSelected. على سبيل المثال، بشكل افتراضي عند تعطيل Button (تشغيل لـ IsEnabled يتم false) ثم القيمة Foreground في نمط السمة هي ما يؤدي لظهور عنصر التحكم بشكل "رمادي الخروج". ولكن إذا قمت بتعيين قيمة محلية Foreground، ذلك اللون الرمادي الخروج العادي سوف يكون overruled في الأسبقية بواسطة مجموعة الخاصية المحلية الخاصة بك، حتى في سيناريو تشغيل الخاصية هذا. توخي الحذر عند إعداد قيم للخصائص التي لها سلوك السمة على مستوى التشغيل وتأكد من أنك لا تتدخل بدون مبرر مع خبرة المستخدم المقصودة لعنصر التحكم هذا.

ClearValue و قيمة الأسبقية

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

راجع أيضًا:

المرجع

DependencyObject

DependencyProperty

المبادئ

نظرة عامة حول خصائص التبعية

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

استدعاء خاصية التبعية و التحقق من صحتها