Placing elements on the page is really simple but many times the six types of shapes available in Silverlight do not suffice to satisfy all the needs. Also often, especially in junction with animations, the need of moving elements on the screen means transforming basic shapes, applying the rules of the simmetry that in Silverlight go under the name of transform.
Applying a trasform means setting the value of the RenderTransform property that is exposed by every class that implements UIElement. Differently from WPF in Silverlight it is possible to apply transform only during the render phase but unfortunately, the LayoutTransform is missing. This is an important limitation of Silverlight because applying the transform during the Rendering pass implies that, the transformed elements, have already been positioned during the layout pass, so this can lead to unwanted overlapping of shapes. However if you need the Layout Transform (e.g. to present a vertical text) you can rely on the LayoutTransformer that is available into the Silverlight Toolkit.
<Border Width="100" Height="100" Background="Red">
<Border.RenderTransform>
<RotateTransform Angle="40" />
</Border.RenderTransform>
</Border>
In Silverlight there is 4 types of possible tranform:
-
Rotation: used to rotate the element around a given point. It is implemented by the class RotateTransform that allows the user to specify an angle in degrees.
-
Translate: used to move an element along the x and y axis of a given amount. The TranslateTransform may seem unuseful since the Canvas layout element appear to allow the same transform but please remember that positioning using Canvas is strongly discouraged
-
Scale: Used to change the size of an element along the x and y axis. Interesting to know that using the ScaleTransform class you can also apply mirror effects using negative values
-
Skew: Used to distort a figure along its axis. SkewTransform allows to bend the shape to which it is applied
Obviously it is absolutely possible you have the need of apply more that a transform to an element. To solve this question there are two possible ways to follow. Before the release 4.0 of Silverlight the sole way was using a TransformGroup class that is a transform that can collect multiple other transformations and make a logical sum of them. Blend 3.0 was known to creates a single TransformGroup with an instance for every type of transform also if you are applying a single type. However here is a sample:
<Border Width="100" Height="100" Background="Red">
<Border.RenderTransform>
<TransformGroup>
<RotateTransform Angle="40" />
<ScaleTransform ScaleX="2" ScaleY=".5" />
</TransformGroup>
</Border.RenderTransform>
</Border>
After the release 4.0 it was added a new type of transform, called CompositeTransform, that is a single class gathering all the properties of the four original transformations. So, Blend 4.0 now creates a single instance of CompositeTransform and it tunes the various properties according with the transformations you applied. Here is how you can convert the previous sample:
<Border Width="100" Height="100" Background="Red">
<Border.RenderTransform>
<TransformGroup>
<CompositeTransform Rotation="40" ScaleX="2" ScaleY=".5" />
</TransformGroup>
</Border.RenderTransform>
</Border>
It is important, however, to note that the two samples of code, also if the properties have the same values, does not led to the same result. This is because the TransformGroup apply the transformation separated, one following the other in the order of appearance, but the CompositeTransform apply the properties in a sole passage. It is all up to you to know if your expectations are in a way or in the other.
Finally, especially when you are applying a RotationTransform, but really with all the other kind of transform, you may want to define the reference point from which the transformation will be applied. The best is to use the RenderTransformOrigin property that allows you to specify the point using a percentage value. The RenderTransformOrigin can contain two coordinates, expressed with a value from 0 to 1, where 0 means 0%, 0.5 means 50% and obviously 1 means 100%. Many transformations have similar properties that are instead specified with absolute coordinates and this makes them difficult to be used.
<Border Width="100" Height="100" Background="Red" RenderTransformOrigin=".5,.5">
<Border.RenderTransform>
<TransformGroup>
<CompositeTransform Rotation="40" ScaleX="2" ScaleY=".5" />
</TransformGroup>
</Border.RenderTransform>
</Border>
Please remember that RenderTransformOrigin is not of type string, but when you specify it in codebehind you have to use the Point class to express the couple of cordinates.