Scale transform in xaml (in a controltemplate) on a button to perform a "zoom"

Matt B picture Matt B · Apr 9, 2010 · Viewed 29.7k times · Source

I've got a button with an image in it and it's being styled by the following:

<ControlTemplate x:Key="IconButton" TargetType="Button">
            <Border>
                <ContentPresenter Height="80" Width="80" />
            </Border>
            <ControlTemplate.Triggers>
                <EventTrigger RoutedEvent="Button.Click">
                    <BeginStoryboard>
                        <Storyboard TargetProperty="Opacity">
                            <DoubleAnimation From="1" To="0.5" Duration="0:0:0.5" />
                            <DoubleAnimation From="0.5" To="1" Duration="0:0:0.5" />
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
                <EventTrigger RoutedEvent="Mouse.MouseEnter">
                    <BeginStoryboard>
                        <Storyboard TargetProperty="Width">
                            <DoubleAnimation From="80" To="95" Duration="0:0:0.2" />
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Cursor" Value="Hand"/>
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>

Button is as follows:

            <Button Template="{StaticResource IconButton}" Name="btnExit">
                <Image Source="Images/Exit.png" />
            </Button>

The problem is that the width doesn't change when my mouse goes over. (Or at least - the width of the image does not...)

I believe there is a "scale" transform I can use to enlarge the button and all it's contents? how would I do that here...?

Thanks.

Answer

Simon Fox picture Simon Fox · Apr 9, 2010

Your template seems to be pretty minimal but I'm assuming your only just getting started on it, however this will help you get started with using a ScaleTransform as opposed to animating the width.

The ScaleTransform can be applied to the RenderTransform property of either the Button itself or just the Border of your template. This could be a TransformGroup if you want to do more than just Scale (i.e. a composite transform consisting of other tranforms such as Translate, Rotate, Skew) but to keep it simple and for examples sake something like the following applies a single ScaleTransform value to the Button:

<Button Template="{StaticResource IconButton}" Name="btnExit">
    <Button.RenderTransform>
        <ScaleTransform ScaleX="1.0" ScaleY="1.0"></ScaleTransform>
    </Button.RenderTransform>
    <Image Source="Images/Exit.png" />
</Button>

or this to apply to the Border of the ControlTemplate:

<ControlTemplate x:Key="IconButton" TargetType="Button">
    <Border Background="Blue" x:Name="render">
        <Border.RenderTransform>
            <ScaleTransform ScaleX="1.0" ScaleY="1.0"></ScaleTransform>
        </Border.RenderTransform>
        <ContentPresenter Height="80" Width="80" />
    </Border>
    ...
    ...

Next you will want to change your MouseEnter trigger to target that property and for width you will want to target the ScaleX property of the ScaleTransform. The following Storyboard will scale the Button 2.5 times in the X direction (add TargetName="render" to <Storyboard... if you have chosen to apply the Transform to the Border as opposed to the Button).

<EventTrigger RoutedEvent="Mouse.MouseEnter">
    <BeginStoryboard>
        <Storyboard TargetProperty="RenderTransform.ScaleX">
            <DoubleAnimation To="2.5" Duration="0:0:0.2" />
        </Storyboard>
    </BeginStoryboard>
</EventTrigger>

If you were to use a TransformGroup with a number of transforms you would change the TargetProperty value to something like RenderTransform.(TransformGroup.Children)[0].ScaleX assuming the ScaleTransform is the first child of the group.

This should get you up and running with what you need and you can take it where you want from there...

HTH