Dependency properties (DPs) are a special type of properties introduced in WPF and Silverlight. Just like the usual .NET properties, they describe a property of a .NET object. Unlike the usual .NET properties, their storage does not take space within the class that uses them. Rather, they are stored in some static collections, indexed, and accessed by the corresponding objects.
Silverlight and WPF provide natural ways to animate the dependency properties using Storyboard objects (which are described later in the chapter).
Silverlight and WPF also have natural mechanisms to bind two dependency properties together (or a usual property to a dependency property) so that changing one of them will trigger the other to change.
Now let's define the RotationAngle
dependency property of a type double
within this class. Put the cursor between the curly brackets defining the body of the class and type propdp
followed by a tab keystroke.
Follow the instructions in Appendix D, Using Snippets, to set up the name, type, and default value of the property.
public class SpinningControl : Control { #region RotationAngle Dependency Property // Dependency Properties' getter and setter for accessing the//DP as // if it is a usual property public double RotationAngle { get { return (double)GetValue(RotationAngleProperty); } set { SetValue(RotationAngleProperty, value); } } // static field for storing and accessing the DPs by object//reference public static readonly DependencyProperty RotationAngleProperty = DependencyProperty.Register ( "RotationAngle", // DP name typeof(double), // DP type typeof(SpinningControl), // Class defining the DP new PropertyMetadata(0.0) // DP's default value ); #endregion RotationAngle Dependency Property }
You might have noticed that the RotationAngle
property within the SpinningControl
class does not refer to any object field. Rather, it uses GetValue
and SetValue
methods inherited from DependencyObject
to get and set the dependency objects correspondingly. The field values themselves are stored within the RotationAngleProperty
static class member, and individual objects of the class SpinningControl
get their RotationAngle
property values from this static field via their object reference (using the functionality embedded within the DependencyObject
class).
This is one of the advantages of using the dependency properties – the SpinningControl
object that does not set the property does not need any extra space for this property; it gets the default from the static RotationAngleProperty
structure defined once for all the objects of the same class. Take a look at the following section within DP's definition:
public double RotationAngle { get { return (double)GetValue(RotationAngleProperty); } set { SetValue(RotationAngleProperty, value); } }
It provides a way to access the dependency property as a usual .NET property. Many .NET calls to the DP, however, are not using these get and set accessors; instead such calls use the DependencyObject
class GetValue()
and SetValue()
methods directly. Because of this, you should not add any code to these property accessors – such a code simply won't be executed in many cases.
This is all we need to define a lookless control – just a class extending Control
and containing some non-visual properties (usually DPs), functions, and events. Such a control is called lookless because it does not define any visual presentation for itself. Visual presentation of a lookless control is defined by a control template, which is usually represented by XAML code residing in some XAML resource file. The advantage of lookless controls lies in the fact that you do not have to change the control itself in order to achieve various different visual representations. All you need to do is to change the template. Since it is the control itself and not its template that is responsible for interacting with the rest of the application, by changing the templates one can completely change the visual presentation of the application without affecting any underlying logic. More on lookless controls can be found at http://tinyurl.com/lookless.
For most of the samples within this book, I am using lookless controls since this is the best practice, even though it is not related to the subject of animations.