مشاركة عبر


خصائص تبعية مجموعة حسب النوع

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

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

  • تنفيذ التبعية لخاصية مجموعة من نوع
  • تهيئة مجموعة خارج القيمة الافتراضية
  • الإعلام عن ربط قيمة التغييرات صواب مجموعة خصائص
  • موضوعات ذات صلة

تنفيذ التبعية لخاصية مجموعة من نوع

لتبعية الخاصية بشكل عام، النقش تطبيق اتباع يتم تعريف CLR خاصية المجمّع ، حيث التي خاصية النسخ بواسطة DependencyProperty معرف بدلاً من حقل أو تركيبة أخرى. اتبع هذا النقش؟ نفس عند تطبيق نوع مجموعة خاصية. ومع ذلك ، خاصية جمع من نوع يدخل بعض التعقيد للنمط كلما نوع محتواة ضمن مجموعة هو في حد ذاته DependencyObject أو Freezable اشتقاق فئة.

تهيئة مجموعة خارج القيمة الافتراضية

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

خذ بعين الاعتبار المثال التالي: يوضح المقطع التالي من المثال التعريف فئة Aquarium. تعريف الفئة في مجموعة نوع تبعية الخاصية AquariumObjects ، الذي يستخدم في عام List<T> نوع مع FrameworkElement نوع القيد. في Register(String, Type, Type, PropertyMetadata) لاستدعاء الخاصية التبعية ، يؤسس بيانات التعريف القيمة الافتراضية أن عام جديد List<T>.

    Public Class Fish
        Inherits FrameworkElement
    End Class
    Public Class Aquarium
        Inherits DependencyObject
        Private Shared ReadOnly AquariumContentsPropertyKey As DependencyPropertyKey = DependencyProperty.RegisterReadOnly("AquariumContents", GetType(List(Of FrameworkElement)), GetType(Aquarium), New FrameworkPropertyMetadata(New List(Of FrameworkElement)()))
        Public Shared ReadOnly AquariumContentsProperty As DependencyProperty = AquariumContentsPropertyKey.DependencyProperty

        Public ReadOnly Property AquariumContents() As List(Of FrameworkElement)
            Get
                Return CType(GetValue(AquariumContentsProperty), List(Of FrameworkElement))
            End Get
        End Property


...


    End Class
public class Fish : FrameworkElement { }
public class Aquarium : DependencyObject
{
    private static readonly DependencyPropertyKey AquariumContentsPropertyKey = 
        DependencyProperty.RegisterReadOnly(
          "AquariumContents",
          typeof(List<FrameworkElement>),
          typeof(Aquarium),
          new FrameworkPropertyMetadata(new List<FrameworkElement>())
        );
    public static readonly DependencyProperty AquariumContentsProperty =
        AquariumContentsPropertyKey.DependencyProperty;

    public List<FrameworkElement> AquariumContents
    {
        get { return (List<FrameworkElement>)GetValue(AquariumContentsProperty); }


...


}

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

          Dim myAq1 As New Aquarium()
          Dim myAq2 As New Aquarium()
          Dim f1 As New Fish()
          Dim f2 As New Fish()
          myAq1.AquariumContents.Add(f1)
          myAq2.AquariumContents.Add(f2)
          MessageBox.Show("aq1 contains " & myAq1.AquariumContents.Count.ToString() & " things")
          MessageBox.Show("aq2 contains " & myAq2.AquariumContents.Count.ToString() & " things")
Aquarium myAq1 = new Aquarium();
Aquarium myAq2 = new Aquarium();
Fish f1 = new Fish();
Fish f2 = new Fish();
myAq1.AquariumContents.Add(f1);
myAq2.AquariumContents.Add(f2);
MessageBox.Show("aq1 contains " + myAq1.AquariumContents.Count.ToString() + " things");
MessageBox.Show("aq2 contains " + myAq2.AquariumContents.Count.ToString() + " things");

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

لتصحيح هذه المشكلة ، يجب إعادة تعيين الخاصية قيمة الاعتماد على جمع نسخة فريدة من نوعها ، وذلك كجزء من الدعوة منشئ الفئة. لأن الخاصية هي خاصية التبعية للقراءة فقط ، يمكنك استخدام SetValue(DependencyPropertyKey, Object) أسلوب لتعيين, باستخدام DependencyPropertyKey التي قابلة للوصول فقط داخل الفئة.

        Public Sub New()
            MyBase.New()
            SetValue(AquariumContentsPropertyKey, New List(Of FrameworkElement)())
        End Sub
public Aquarium() : base()
{
    SetValue(AquariumContentsPropertyKey, new List<FrameworkElement>()); 
}

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

قد يكون هناك تباين بسيط على هذا النقش؟ إذا اخترت أن المجموعة خاصية تكون للقراءة والكتابة. في هذه الحالة، قد استدعاء أسلوب استرجاع قيمة مجموعة عامة صواب يمكن استدعاء مُنشئ للقيام التهيئة الذي هل لا تزال توقيع nonkey SetValue(DependencyProperty, Object) داخل برنامج تضمين مجموعة الخاص بك باستخدام عام DependencyProperty معرف.

الإعلام عن ربط قيمة التغييرات صواب مجموعة خصائص

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

لتمكين الربط subproperty في مجموعة كائن تبعية إنشاء الخاصية مجموعة الكتابة FreezableCollection<T> ، مع قيد نوع لمجموعة إلى أي DependencyObject اشتقاق فئة.

راجع أيضًا:

المرجع

FreezableCollection<T>

المبادئ

XAML وفئات مخصصة ل WPF

نظرة عامة لربط البيانات

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

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

الخاصية التبعية بيانات التعريف