Collection-Type Dependency Properties
This page is specific to:Microsoft Version:
Silverlight 3
Silverlight
Collection-Type Dependency Properties

This topic provides guidance and suggested patterns for how to implement a dependency property where the type of the property is a collection type.

Prerequisites

This topic assumes that you understand dependency properties from the perspective of a consumer of existing dependency properties on Silverlight classes, and that you have read Dependency Properties Overview and Custom Dependency Objects and Dependency Properties.

Implementing a Collection-Type Dependency Property

For a dependency property in general, the implementation pattern is to define a CLR property wrapper, where that property is backed by a DependencyProperty identifier rather than a field or other construct. You follow this same pattern when you implement a collection-type property. However, if the type that is contained in the collection is itself a DependencyObject derived class, the pattern becomes more complex.

Initializing the Collection Beyond the Default Value

When you create a dependency property, you do not specify the property default value as the initial field value. Instead, you specify the default value through the dependency property metadata. If your property is a reference type, the default value specified in dependency property metadata is not a default value per instance; instead it is a default value that applies to all instances of the type. Therefore, you must be careful to not use the singular static collection defined by the collection property metadata as the working default value for newly created instances of your type. Instead, you must make sure that you deliberately set the collection value to a unique (instance) collection as part of your class constructor logic. Otherwise, you will create an unintentional singleton class.

Consider the following example. The following section of the example shows the definition for an Aquarium class. The class defines the collection-type dependency property AquariumObjects, which uses the generic List<(Of <(T>)>) type with a FrameworkElement type constraint. In the Register(String, Type, Type, PropertyMetadata) call for the dependency property, the metadata establishes the default value to be a new generic List<(Of <(T>)>).

Public Class Aquarium 
    Inherits DependencyObject 
    Private Shared ReadOnly AquariumContentsProperty As DependencyProperty = DependencyProperty.Register("AquariumContents", GetType(List(Of FrameworkElement)), GetType(Aquarium), New PropertyMetadata(New List(Of FrameworkElement)())) 
    Public Property AquariumContents() As List(Of FrameworkElement) 
        Get 
            Return DirectCast(GetValue(AquariumContentsProperty), List(Of FrameworkElement)) 
        End Get 
        Set(ByVal value As List(Of FrameworkElement)) 
            SetValue(AquariumContentsProperty, DirectCast(value, List(Of FrameworkElement))) 
        End Set 
    End Property 
    Public Sub New() 
        MyBase.New() 
    End Sub 
End Class


However, if you leave the code as shown, that single list default value is shared for all instances of Aquarium. If you ran the following test code, which is intended to show how you would instantiate two separate Aquarium instances and add a single different Fish to each of them, you would see a surprising result: instead of each collection having a count of one, each collection has a count of two!

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)


This is because each Aquarium added its Fish to the default value collection, which resulted from a single constructor call in the metadata and is therefore shared between all instances. This situation is almost never what you want.

To correct this problem, you must reset the collection dependency property value to a unique instance, as part of the class constructor call.

    Public Sub New() 
        MyBase.New() 
        SetValue(AquariumContentsProperty, New List(Of FrameworkElement)()) 
    End Sub 
End Class 


See Also

Concepts

© 2010 Microsoft Corporation. All rights reserved.   Terms of Use | Trademarks | Privacy Statement
Page view tracker
Rate the Lightweight library
x
Lightweight builds on ScriptFree (loband) by adding features you've requested: a SearchBox and default code language selection.
Do you like the SearchBox?
Do you like the tabbed code blocks?
How useful is this topic?
Tell us more.
Thanks
x
You're helping to improve MSDN Online.
Feedback
Switch View
Classic
Lightweight Beta
ScriptFree
Switch View