.NET 4.0+WPF Transforms - Composite Transforms
The one hundred and forty-fifth part of the Windows Presentation Foundation Fundamentals tutorial continues to look at transforms. This article examines composite transforms, which combine several transforms into a single action.
TransformGroup
In the previous four articles we've seen four basic transform operations that you can use to scale, translate, rotate and skew user interface elements. In some situations you might want to apply more than one of these to a control or shape, perhaps rotating and translating an item in one action. This type of transform can be achieved using the TransformGroup class.
TransformGroup inherits from the same key base class as the other transforms we've seen, meaning it can be applied to either the RenderTransform or LayoutTransform property in the same manner. The class includes a property named, "Children" that holds the individual transforms to be applied, in the order in which you want them to be processed.
To demonstrate, create a new WPF application in Visual Studio. Name the solution, "TransformGroupDemo". Once prepared, replace the main window's XAML with the following:
<Window x:Class="TransformGroupDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Transform Demo" Height="230" Width="250">
<Grid>
<Rectangle Fill="Red" Width="100" Height="50"/>
<Rectangle Fill="#800000FF" Width="100" Height="50"/>
</Grid>
</Window>
The resultant window holds two Rectangles. The first is red and the second is a partially transparent blue. As both rectangles are the same size and in the same place, the window appears to show a single, purple shape.
Applying a Composite Transform
When using XAML, you can set the Children property of the TransformGroup without specifically including the property's name. You simply define all of the child transforms within the TransformGroup's element.
To demonstrate, replace the XAML for the red rectangle with the following code:
<Rectangle Fill="Red" Width="100" Height="50">
<Rectangle.RenderTransform>
<TransformGroup>
<RotateTransform Angle="45"/>
<TranslateTransform X="50" Y="-50"/>
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
The above transform first rotates the rectangle by 45 degrees, then moves it 50 device-independent units upwards and to the right. The result is shown below. You can see how the shape has been rotated around the top-left of its bounding box before being translated.
Transform Order
The order of the child transforms of a TransformGroup is important. They are applied one at a time, starting with the first item in the list. If the order is changed, the results can differ. For example, let's use the same transforms but in the reverse order for the blue rectangle:
<Rectangle Fill="#800000FF" Width="100" Height="50">
<Rectangle.RenderTransform>
<TransformGroup>
<TranslateTransform X="50" Y="-50"/>
<RotateTransform Angle="45"/>
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
This time the rectangle is moved 50 device-independent units upwards and to the right. It is then rotated by the same 45 degrees around the same default centre point at co-ordinates (0,0) of the original bounding box. Because the shape has moved further away from this centre point, the rotation causes more movement and the blue rectangle does not appear in the same position as the red one.
20 March 2015