First, a hearty thank you to "obsid" who wrote a great comment noting that by using reflector you can find that the documentation is not yet updated and System.Windows.PropertyMetadata's constructor is overloaded. While I am a fan of writing reflective programs (see chapter 20 Programming C# 3.0), for those of you who don't particularly want to dive into this somewhat obscure topic, an easier proof of obsid's point can be obtained in Visual Studio by opening the Object Browser and searching for PropertyMetaData where you will find the following:
As you may be able to see, there are five overloads: a default constructor, one that takes an object, another that takes an object and a callback, a fourth that takes an object, a callback and a "CoerceValueCallback" and finally a constructor that take a callback alone. Highlighting any of these causes it to be summarized in the associated window in the object browser.
A Note on Feedback: I would encourage feedback and corrections, but you are not shy; so keep it coming. As for the specific note about default values, please be assured that issue will be covered when Dependency Property Precedence is covered.
Advantages of Dependency Properties
In the previous discussion, I talked about the "cost" of DPs; specifically the learning curve. The advantages manifestly outweigh the cost and today I'll begin to discuss what you get for this somewhat byzantine system.
The short answer is that Dependency properties were invented to support four forms of "late binding" for properties that are not easily supported when a property is backed by a field:
- Data binding
- Styles and Templates
Support for each of these can be accomplished in other ways, of course, but the Dependency Properties system is faster and more efficient than the alternatives.
Note that the Dependency Properties system was not invented for Silverlight, it was originally invented for WPF and then adapted for Silverlight. In fact, some of the breaking changes from Beta2 to RC0 are in service to bringing the Silverlight version more in line with the WPF version.
Resources are typically specified as child elements of a page root element, or of the application (e.g., in App.xaml)
Data binding works through a specific markup extension syntax in XAML, or the Binding object in code. With data binding, the final property value determination is deferred until run time, at which time the value is obtained from a data source.
Styles and Templates
Any property of a control can be changed from its declared appearance by the use of a Style or Template and this may be changed dynamically and at run time.
Animation is implemented through Storyboards where the target of the animation is the property of a control. The value of the property must be able to change rapidly and very frequently.
All of this would be accomplished in traditional .NET through reflection, but reflection is a notoriously slow process, not nearly fast enough for data binding, let alone animation.
One particular, common and powerful use of dependency properties is the creation of attached properties — the illusion of a property in an object that is actually a property of another (typically containing) object. Thus, when a Textblock is declared as
<Textblock text="Who put me here?" grid.Column="1" Grid.Row="0" x:Name="myTB" />
The properties Grid.Column and Grid.Row are not properties of the TextBlock but are attached to the TextBlock through the use of a form of Dependency Properties called Attached Properties.
One of the aspects of Dependency properties that make them very valuable in data binding and animation scenarios is that they have a very well defined precedence for how their value is determined when more than one potential source affects them (that is, a property might potentially set by data binding, a style and animation; which one actually sets the property?)
That is the topic for the next installment.