#801 – Creating a Mirror Image Using a RenderTransform

You can flip an object horizontally, so that you get a mirror image, using a ScaleTransform with the ScaleX value of -1.  If you use a LayoutTransform, the object will be layed out as intended after doing the transformation.

You might, however, want to do a transform to get a mirror image only after laying everything out.  To do this, you use a RenderTransform.  You still set the ScaleX property to -1, but you also need to set the RenderTransformOrigin to be located in the middle of the object being transformed.

    <StackPanel RenderTransformOrigin="0.5,0.5">
        <StackPanel.RenderTransform>
            <ScaleTransform ScaleX="-1"/>
        </StackPanel.RenderTransform>

        <Label Content="Earthquake hits San Francisco!" Margin="5"
               FontSize="16" FontFamily="Constantia" />
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
            <DatePicker SelectedDate="4/18/1906"/>
            <Label Content="Horrible!" FontWeight="Bold"/>
        </StackPanel>
        <Button Content="Donate $$ Now" HorizontalAlignment="Center"
                Padding="10,5" Margin="15"/>
    </StackPanel>

801-001

#782 – A RenderTransform Has Better Performance than a LayoutTransform

When you transform a 2D element, you specify the desired transform as either a layout transform (transform calculated before layout phase) or a render transform (transform calculated before rendering the element).

A render transform has better performance than a layout transform.  This is especially apparent when you are animating a transform.  Whenever a layout transform changes, the panel containing the element that is being transformed needs to recalculate the layout of the children within the panel.  With a render transform, by contrast, the element only needs to be re-rendered.  Because of the additional layout step, a layout transform is more compute intensive than a render transform.

Because of the performance differences, you should use a render transform by default, unless you need the layout of the elements to change when the transform changes.

 

#773 – A Rotation Center Point Can Be Outside an Element

When you use the RenderTransformOrigin property of an element to specify the point of origin for all render transforms, you typically express X and Y as normalized coordinates.  X and Y both range from 0.0 to 1.0 as the position moves from one side of the element to the other.

You can also specify X and Y values that are less than 0.0 or greater than 1.0, indicating a point that is outside the element’s boundaries.  (Possibly quite distant from the element).

In the example below, the origin for a rotation transform is set to be off to the right of a Button.  The Slider allows you to try out different rotation angles at runtime.

    <StackPanel Orientation="Vertical">
        <Button Content="Push Me" HorizontalAlignment="Center" Padding="10,5" Margin="5"/>
        <Button Content="And Me" HorizontalAlignment="Center" Padding="10,5" Margin="5"
                RenderTransformOrigin="3.0,1.0" >
            <Button.RenderTransform>
                <RotateTransform Angle="{Binding ElementName=sliAngle, Path=Value}" />
            </Button.RenderTransform>
        </Button>
        <Slider Name="sliAngle" Minimum="-180"  Maximum="180" Value="-20" Margin="25,100"/>
    </StackPanel>

773-001
773-002

#770 – The Difference Between a LayoutTransform and a RenderTransform

When you are transforming user interface elements using a 2D transform, you can choose one of two types of transforms.

  • LayoutTransform transforms elements before they are layed out by the parent panel
  • A RenderTransform transforms element after they are layed out by the parent panel (but before they are rendered)

Which one you use depends on whether you want transform and then lay out (use LayoutTransform) or to lay out and then transform (use RenderTransform).  (Note: You could also use both types).

    <StackPanel Orientation="Horizontal">
        <StackPanel Orientation="Vertical">
            <Label Content="LayoutTransform"/>
            <Button Content="Push Me" Style="{StaticResource buttonStyle}"/>
            <Button Content="Push Me" Style="{StaticResource buttonStyle}">
                <Button.LayoutTransform>
                    <RotateTransform Angle="20"/>
                </Button.LayoutTransform>
            </Button>
            <Button Content="Push Me" Style="{StaticResource buttonStyle}">
                <Button.LayoutTransform>
                    <RotateTransform Angle="-20"/>
                </Button.LayoutTransform>
            </Button>
        </StackPanel>
        <StackPanel Orientation="Vertical">
            <Label Content="RenderTransform"/>
            <Button Content="Push Me" Style="{StaticResource buttonStyle}"/>
            <Button Content="Push Me" Style="{StaticResource buttonStyle}">
                <Button.RenderTransform>
                    <RotateTransform Angle="20"/>
                </Button.RenderTransform>
            </Button>
            <Button Content="Push Me" Style="{StaticResource buttonStyle}">
                <Button.RenderTransform>
                    <RotateTransform Angle="-20"/>
                </Button.RenderTransform>
            </Button>
        </StackPanel>
    </StackPanel>

770-001

#569 – Setting Transforms from within Blend

You can set both layout and render transforms for an UIElement from within Blend.

To configure a transform, just select the user interface element and then find the Transform area of the Properties panel.  You’ll see that you can set properties for both layout and render transforms.

You can configure a number of different transforms.

A Translation moves an element left/right or up/down.

A rotation transform rotates the element.

A scale transform scales the element.  You can change the element’s X and Y dimensions independently.

A skew transformation slants the element, relative to the X or Y dimension (or both).

You can change the centerpoint of the element, with respect to other translations that you apply.

You can also flip the control horizontally or vertically.

#480 – ZIndex Values and Render Transforms

It’s possible for controls to overlap each other when using a RenderTransform–even in containers that don’t normally overlap their child controls.

In the example below, the first Button in a StackPanel is rotated and ends up overlapping the second Button.

    <StackPanel Margin="10">
        <Button Content="Alpha" HorizontalAlignment="Center" Padding="20,0" >
            <Button.RenderTransform>
                <RotateTransform Angle="45"/>
            </Button.RenderTransform>
        </Button>
        <Button Content="Bravo" HorizontalAlignment="Center" Padding="20,0" />
    </StackPanel>


Whenever overlapping occurs, the containing panel’s attached ZIndex property dictates the overlapping order of the child controls. With default ZIndex values of 0, child controls appearing later in the XAML are rendered on top of earlier controls.

You can explicitly control the overlap order by specifying ZIndex values.  In the previous example, if we give the first button a ZIndex of 2 and the second button a ZIndex of 1, their overlap order is reversed.