One constraint on the dependency properties is that they have to be defined within a class that uses them. In many cases, however, developers might want to add properties to an object of a predefined class without extending the class. WPF and Silverlight came up with a new concept that allows doing just that – attached properties (APs). APs can be defined in some (usually static) class and can be used to attach properties to any object derived from a DependencyObject
.
An attached property sample can be found in the SpinningWithAttachedPropertySample
folder. To create your own sample, create a new project and add a C# file/class to it called AttachedProperties
. Make this class static and use the propa
snippet to create the RotateAngle
attached property in it:
#region RotationAngle attached Property public static double GetRotationAngle(DependencyObject obj) { return (double)obj.GetValue(RotationAngleProperty); } public static void SetRotationAngle(DependencyObject obj, double value) { obj.SetValue(RotationAngleProperty, value); } public static readonly DependencyProperty RotationAngleProperty = DependencyProperty.RegisterAttached ( "RotationAngle", typeof(double), typeof(AttachedProperties), new PropertyMetadata(0.0) ); #endregion RotationAngle attached Property
You can see that unlike dependency properties, the attached properties have two static accessor methods GetRotationAngle
and SetRotationAngle
.
Now we can animate this attached property within the MainPage.xaml
file in a very similar way to animating the dependency property. In the following section, we show the regions of XAML code that are different from the dependency property code.
In our attached property animation project, we will define a Storyboard
object in exactly the same way as we did for the dependency property, the only difference is that we cannot specify Storyboard.TargetProperty
within XAML:
<UserControl.Resources> <Storyboard x:Key="RotationStoryboard" Storyboard.TargetName="TheRotatingRectangle"> <DoubleAnimation BeginTime="00:00:00" Duration="00:00:01" From="0" To="360" RepeatBehavior="Forever" /> </Storyboard> </UserControl.Resources>
Unfortunately, Silverlight does not allow a storyboard to reference a custom attached property in XAML. Due to this limitation, we are forced to add such a reference in the C# code-behind.
The following is the XAML definition of a spinning Rectangle
. The only difference between this code and the DP-related code previously presented is that we are using the full path within parentheses to point to the attached property within the Binding definition:
<Rectangle x:Name="TheRotatingRectangle" Fill="Orange" Width="100" Height="30" RenderTransformOrigin="0.5,0.5"> <Rectangle.RenderTransform> <RotateTransform Angle="{Binding Path=(SpinningWithAP:AttachedProperties.RotationAngle), Mode=OneWay, ElementName=TheRotatingRectangle}"/> </Rectangle.RenderTransform> </Rectangle>
You can see that the visual element does not have to be a custom control, we can use an attached property on an element built into Silverlight – Rectangle
.
Finally, as was previously stated, due to a Silverlight limitation, we have to specify the storyboard's TargetProperty
within the C# code. We can do this in the MainPage
constructor as shown in the following snippet:
public MainPage() { InitializeComponent(); Storyboard rotationStoryboard = (Storyboard) this.Resources["RotationStoryboard"]; Storyboard.SetTargetProperty ( rotationStoryboard, new PropertyPath(AttachedProperties.RotationAngleProperty) ); }