#1,202 – Using a Color Animation to Draw Emphasis to Something

There are times when you might want to draw a user’s attention to some user interface element, for example when some event causes the contents of the element to change. A ColorAnimation on the Background of the element is a nice way to do that.

Below, we have a TextBlock that binds to a string property and a Button that changes that property’s value. We set up a style for the TextBlock containing an EventTrigger that fires whenever the target of the binding changes, i.e. the trigger will fire whenever the value of the Text property changes.

In the trigger, we have a Storyboard continuing two animations that run consecutively. The first fades in the background color and the second fades back to the original transparent value. The first animation is shorter, so that we have a longer fade out.

Here’s the XAML fragement:

<Window.Resources>
    <ResourceDictionary>
        <Style x:Key="LookAtMe" TargetType="TextBlock">
            <Setter Property="Background" Value="Transparent"/>
            <Style.Triggers>
                <EventTrigger RoutedEvent="Binding.TargetUpdated">
                    <EventTrigger.Actions>
                        <BeginStoryboard>
                            <Storyboard>
                                <ColorAnimation Storyboard.TargetProperty="(TextBlock.Background).(SolidColorBrush.Color)" 
                                                From="Transparent" To="Magenta" FillBehavior="Stop" 
                                                BeginTime="0:0:0" Duration="0:0:0.3"/>
                                <ColorAnimation Storyboard.TargetProperty="(TextBlock.Background).(SolidColorBrush.Color)" 
                                                From="Magenta" To="Transparent" 
                                                BeginTime="0:0:0.3" Duration="0:0:1"/>
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger.Actions>
                </EventTrigger>
            </Style.Triggers>
        </Style>
    </ResourceDictionary>
</Window.Resources>
    
    <StackPanel Margin="10">
        <TextBlock Text="{Binding SomeText, NotifyOnTargetUpdated=True}" 
                   Style="{StaticResource LookAtMe}"/>
        <Button Content="Do Something" 
                Margin="0,10,0,0" HorizontalAlignment="Center" 
                Click="btnDoSomething_Click"/>
    </StackPanel>

In the code-behind, we have the SomeText property and code to change this property whenever the button is pressed.

private string _someText = "Original text";
public string SomeText
{
    get { return _someText; }
    set
    {
        if (value != _someText)
        {
            _someText = value;
            RaisePropChanged("SomeText");
        }
    }
}

private int nextNum = 1;
private void btnDoSomething_Click(object sender, RoutedEventArgs e)
{
    SomeText = string.Format("Change to {0}", nextNum++);
}

public event PropertyChangedEventHandler PropertyChanged = delegate { };

private void RaisePropChanged(string propname)
{
    PropertyChanged(this, new PropertyChangedEventArgs(propname));
}

When you run this code, the background of the TextBlock flashes magenta whenever you click on the button.

#1,164 – Using Animation to Bounce a Control

The XAML fragment below will start a Button bouncing when you click on it.  This uses the BounceEase object as an easing function.  You can play with the animation duration, # bounces, and “bounciness” to get different effects.

	<Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Button Content="Click Me" Margin="20,5,20,35"
                VerticalAlignment="Bottom">
            <Button.RenderTransform>
                <TranslateTransform x:Name="transTransform" X="0" Y="0"/>
            </Button.RenderTransform>
            <Button.Triggers>
                <EventTrigger RoutedEvent="Button.Click">
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation From="0" To="35" Duration="00:00:01" 
                                    Storyboard.TargetName="transTransform" 
                                    Storyboard.TargetProperty="Y"
                                    AutoReverse="True" RepeatBehavior="Forever">
                                <DoubleAnimation.EasingFunction>
                                    <BounceEase Bounces="1" EasingMode="EaseOut"
                                                Bounciness="2" />
                                </DoubleAnimation.EasingFunction>
                            </DoubleAnimation>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
            </Button.Triggers>
        </Button>
        <Border Grid.Row="1"
            BorderBrush="Black" BorderThickness="10"/>
    </Grid>

#779 – Animating a Rotation Transform

Here’s one more example of an animation of a 2D transform.  In this case, we animate a rotation transform of an element so that the element continually spins around.

    <Grid>
        <Label Content="Gambling now legal in Nevada" Background="Plum"
               HorizontalAlignment="Center" VerticalAlignment="Center"
               Padding="20,10" FontSize="16"
               RenderTransformOrigin="0.5,0.5">
            <Label.RenderTransform>
                <RotateTransform x:Name="rotTransform" />
            </Label.RenderTransform>
            <Label.Triggers>
                <EventTrigger RoutedEvent="Label.Loaded">
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation Storyboard.TargetName="rotTransform"
                                             Storyboard.TargetProperty="Angle"
                                             From="0" To="360" Duration="0:0:2.5"
                                             RepeatBehavior="Forever"/>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
            </Label.Triggers>
        </Label>
    </Grid>

779-001
779-002

#778 – Animating a Scale Transform

Here’s another example of an animation of a 2D transform.  In this case, we animate the scale of the object so that it grows larger and smaller and then repeats the behavior.  This results in a sort of pulsating button.

    <Grid>
        <Button Content="Ship via Wells, Fargo &amp; Co." HorizontalAlignment="Center" VerticalAlignment="Center"
                Padding="20,10" FontSize="16"
                RenderTransformOrigin="0.5,0.5">
            <Button.RenderTransform>
                <ScaleTransform x:Name="scaleTransform" ScaleX="0.98" ScaleY="1.02"/>
            </Button.RenderTransform>
            <Button.Triggers>
                <EventTrigger RoutedEvent="Button.Loaded">
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation Storyboard.TargetName="scaleTransform"
                                             Storyboard.TargetProperty="ScaleX"
                                             From="0.98" To="1.02" Duration="0:0:0.3"
                                             AutoReverse="True" RepeatBehavior="Forever"/>
                            <DoubleAnimation Storyboard.TargetName="scaleTransform"
                                             Storyboard.TargetProperty="ScaleY"
                                             From="0.98" To="1.02" Duration="0:0:0.3"
                                             AutoReverse="True" RepeatBehavior="Forever"/>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
            </Button.Triggers>
        </Button>
    </Grid>

778-001

#777 – Animating a Transform

You can animate any of the 2D transforms applied to an element by using a Storyboard that contains an object that derives from AnimationTimeline.

In the example below, we use two DoubleAnimation objects to animate the X and properties of a TranslateTransform, so that the TextBlock wanders around the screen.

For the X property of the transform, we specify that we want it to vary from -100 to 100 and then back again, taking 0.7 seconds and then repeating the pattern forever.  We do something similar for Y, but using a different time period.

    <Grid>
        <TextBlock Text="We shall overcome" HorizontalAlignment="Center" VerticalAlignment="Center"
                   Padding="20,10" Background="PaleGoldenrod" FontSize="16">
            <TextBlock.RenderTransform>
                <TranslateTransform x:Name="transTransform" X="-100" Y="-80"/>
            </TextBlock.RenderTransform>
            <TextBlock.Triggers>
                <EventTrigger RoutedEvent="TextBlock.Loaded">
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation Storyboard.TargetName="transTransform"
                                             Storyboard.TargetProperty="X"
                                             From="-100" To="100" Duration="0:0:0.7"
                                             AutoReverse="True" RepeatBehavior="Forever"/>
                            <DoubleAnimation Storyboard.TargetName="transTransform"
                                             Storyboard.TargetProperty="Y"
                                             From="-80" To="80" Duration="0:0:1.5"
                                             AutoReverse="True" RepeatBehavior="Forever"/>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
            </TextBlock.Triggers>
        </TextBlock>
    </Grid>

777-001
777-002

#686 – Using Animation to Make an Image Pulse

You can animate the opacity of an Image element to make it appear to pulse.  Below is one example of how to do this, using a Storyboard.  We animate the image’s Opacity property, down to 10% opaque over half a second and then back again.

    <StackPanel Margin="15">
        <CheckBox Content="Turn On" Margin="10" IsChecked="True"/>
        <StackPanel Orientation="Horizontal">
            <CheckBox Content="Tune In" Margin="10" VerticalAlignment="Center"/>
            <Image Name="funkyArrow" Source="Arrow.png" Margin="15,0">
                <Image.Triggers>
                    <EventTrigger RoutedEvent="Image.Loaded">
                        <BeginStoryboard>
                            <Storyboard>
                                <DoubleAnimation Storyboard.TargetName="funkyArrow"
                                    Storyboard.TargetProperty="Opacity"
                                    From="1.0" To="0.1" Duration="0:0:0.5"
                                    AutoReverse="True" RepeatBehavior="Forever"/>
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger>
                </Image.Triggers>
            </Image>
        </StackPanel>
        <CheckBox Content="Drop Out" Margin="10"/>
    </StackPanel>


#7 – Property-Based Animation

Animation is one of the core features of WPF.  Unlike older frameworks, like Windows Forms, you don’t implement animation using timers and rendering the animation frame by frame.  Instead, WPF uses property-based animation, where you animate graphical elements by declaratively specifying how one of its properties should change, over time.

You can implement animation by writing code or by specifying the desired animated effect declaratively, in XAML.  You can also use the tools in Blend 4 to create WPF animations.

As an example, here’s a snippet of XAML that defines a button that will change it’s Height and Width properties, forever expanding and contracting:

<Button Content="Click Me" Height="25" HorizontalAlignment="Left" Margin="25,25,0,0" Name="button1" VerticalAlignment="Top" Width="100" >
    <Button.Triggers>
        <EventTrigger RoutedEvent="Button.Loaded">
            <BeginStoryboard>
                <Storyboard>
                    <DoubleAnimation
                        Storyboard.TargetName="button1"
                        Storyboard.TargetProperty="Width"
                        From="100" To="105" Duration="0:0:0.3"
                        AutoReverse="True" RepeatBehavior="Forever"/>
                    <DoubleAnimation
                        Storyboard.TargetName="button1"
                        Storyboard.TargetProperty="Height"
                        From="25" To="30" Duration="0:0:0.5"
                        AutoReverse="True" RepeatBehavior="Forever"/>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Button.Triggers>
</Button>

More