Colin Bacon, web developer.

Extending the animation - fading out with storyboards and behaviours - WinRT | Windows 8.1 store apps

Extending the animation - fading out with storyboards and behaviours - WinRT | Windows 8.1 store apps

Previously we looked at how to fade out an element using storyboards and behaviours. This time we extend our code by fading in another element.

This post follows on from Creating a simple fade animation using storyboards and behaviours. Having displayed a message to the user and fading it out I then needed to fade in "status" text.

The status text will be hidden to the user until the original message has faded out. Then it will fade in. We will use the same approach as before, a storyboard and behaviour, with one slight difference. As the status message will be hidden we will have to change the visibility before fading in.

Here is our TextBlock.

<TextBlock x:Name="StatusTextBlock"
           Visibility="Collapsed"
           Text="{Binding StatusText}"> 
</TextBlock>

Firstly, let's add the behaviour.

<interactivity:Interaction.Behaviors>
    <core:DataTriggerBehavior Binding="{Binding HasProcessComplete}" Value="True">
        <media:ControlStoryboardAction Storyboard="{StaticResource FadeIn}"/>
    </core:DataTriggerBehavior>
</interactivity:Interaction.Behaviors>

The interaction behaviour is bound to HasProcessComplete. This is the same property that triggers the first message we show to the user. As we do not want the status text to fade in immediately the KeyTime is set to start when the first message fades out.

Here's the storyboard.

<Storyboard x:Name="FadeIn">
    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="StatusTextBlock"
                                   Storyboard.TargetProperty="(UIElement.Visibility)">
        <DiscreteObjectKeyFrame KeyTime="0:0:4">
            <DiscreteObjectKeyFrame.Value>
                <Visibility>Visible</Visibility>
            </DiscreteObjectKeyFrame.Value>
        </DiscreteObjectKeyFrame>
    </ObjectAnimationUsingKeyFrames>
    <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)"
                                   Storyboard.TargetName="IssueTextBlock">
        <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
        <EasingDoubleKeyFrame KeyTime="0:0:4" Value="0"/>
        <EasingDoubleKeyFrame KeyTime="0:0:5" Value="1"/>
    </DoubleAnimationUsingKeyFrames>
</Storyboard>

To set the visibility use ObjectAnimationUsingKeyFrames targeting the TextBlock and the Visibility property. Then set the KeyTime on the DiscreteObjectKeyFrame to the end time of the first animation (the message text). Then use the same animation as before to animate opacity.

The final XAML for the status text.

<TextBlock x:Name="StatusTextBlock"
       Visibility="Collapsed"
       Text="{Binding StatusText}">
    <TextBlock.Resources>
        <Storyboard x:Name="FadeIn">
            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="StatusTextBlock"
                                           Storyboard.TargetProperty="(UIElement.Visibility)">
                <DiscreteObjectKeyFrame KeyTime="0:0:4">
                    <DiscreteObjectKeyFrame.Value>
                        <Visibility>Visible</Visibility>
                    </DiscreteObjectKeyFrame.Value>
                </DiscreteObjectKeyFrame>
            </ObjectAnimationUsingKeyFrames>
            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)"
                                           Storyboard.TargetName="StatusTextBlock">
                <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
                <EasingDoubleKeyFrame KeyTime="0:0:4" Value="0"/>
                <EasingDoubleKeyFrame KeyTime="0:0:5" Value="1"/>
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>
    </TextBlock.Resources>
    <interactivity:Interaction.Behaviors>
        <core:DataTriggerBehavior Binding="{Binding HasProcessComplete}" Value="True">
            <media:ControlStoryboardAction Storyboard="{StaticResource FadeIn}"/>
        </core:DataTriggerBehavior>
    </interactivity:Interaction.Behaviors>
</TextBlock>

And putting it altogether. Display a message to the user, fade it out and fade in the status text.

<Border Background="Red"
    x:Name="ProcessCompleteAlert"
    Visibility="{Binding HasProcessComplete, Converter={StaticResource BooleanToVisibilityConverter}}">
    <Border.Resources>
        <Storyboard x:Name="Fading">
            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)"
                                           Storyboard.TargetName="ProcessCompleteAlert">
                <EasingDoubleKeyFrame KeyTime="0" Value="1"/>
                <EasingDoubleKeyFrame KeyTime="0:0:3" Value="1"/>
                <EasingDoubleKeyFrame KeyTime="0:0:4" Value="0"/>
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>
    </Border.Resources>
    <TextBlock Text="ALL ITEMS HAVE BEEN PROCESSED"/>
    <interactivity:Interaction.Behaviors>
        <core:DataTriggerBehavior Binding="{Binding HasProcessComplete}" Value="True">
            <media:ControlStoryboardAction Storyboard="{StaticResource Fading}"/>
        </core:DataTriggerBehavior>
    </interactivity:Interaction.Behaviors>
</Border>
<TextBlock x:Name="StatusTextBlock"
       Visibility="Collapsed"
       Text="{Binding StatusText}">
    <TextBlock.Resources>
        <Storyboard x:Name="FadeIn">
            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="StatusTextBlock"
                                           Storyboard.TargetProperty="(UIElement.Visibility)">
                <DiscreteObjectKeyFrame KeyTime="0:0:4">
                    <DiscreteObjectKeyFrame.Value>
                        <Visibility>Visible</Visibility>
                    </DiscreteObjectKeyFrame.Value>
                </DiscreteObjectKeyFrame>
            </ObjectAnimationUsingKeyFrames>
            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)"
                                           Storyboard.TargetName="StatusTextBlock">
                <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
                <EasingDoubleKeyFrame KeyTime="0:0:4" Value="0"/>
                <EasingDoubleKeyFrame KeyTime="0:0:5" Value="1"/>
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>
    </TextBlock.Resources>
    <interactivity:Interaction.Behaviors>
        <core:DataTriggerBehavior Binding="{Binding HasProcessComplete}" Value="True">
            <media:ControlStoryboardAction Storyboard="{StaticResource FadeIn}"/>
        </core:DataTriggerBehavior>
    </interactivity:Interaction.Behaviors>
</TextBlock>