Question

I'm making a Windows Phone 8 app and would like to first fade out and then -- and only then -- actually turn a UIElement's Visibility to "Collapsed". However, I can't figure out how to make them happen asynchronously.

I'm using Storyboards and Blend. Here are my storyboards to toggle my little "Popup" StackPanel:

<VisualStateGroup x:Name="PopupStates">
    <VisualState x:Name="PopupDisplayed">
        <Storyboard>

            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="Popup">
                <DiscreteObjectKeyFrame KeyTime="0">
                    <DiscreteObjectKeyFrame.Value>
                        <Visibility>Visible</Visibility>
                    </DiscreteObjectKeyFrame.Value>
                </DiscreteObjectKeyFrame>
            </ObjectAnimationUsingKeyFrames>

            <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="Popup" d:IsOptimized="True"/>
        </Storyboard>
    </VisualState>

    <VisualState x:Name="PopupHidden">
        <Storyboard>

            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="Popup">
                <DiscreteObjectKeyFrame KeyTime="0">
                    <DiscreteObjectKeyFrame.Value>
                        <Visibility>Collapsed</Visibility>
                    </DiscreteObjectKeyFrame.Value>
                </DiscreteObjectKeyFrame>
            </ObjectAnimationUsingKeyFrames>

            <DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="Popup" d:IsOptimized="True"/>

        </Storyboard>
    </VisualState>
</VisualStateGroup>

How can I time my storyboard events to happen one-after-another?

Was it helpful?

Solution

You can set the BeginTime property of the second animation to be the duration of the first.

From the MSDN page:

The BeginTime property is useful for creating timelines that play in a sequence: by increasing the BeginTime of successive timelines that share the same parent Storyboard, you can stagger their play times.

The example on that page shows how you use it:

        <!-- Animates the rectangle's width. No 
             BeginTime specified so by default begins 
             as soon as it's parent (the Storyboard)
             begins. -->
        <DoubleAnimation 
          Storyboard.TargetName="MyAnimatedRectangle" 
          Storyboard.TargetProperty="Width"
          To="300" Duration="0:0:1" />

        <!-- Animates the rectangle's opacity. A BeginTime
             of 3 seconds specified so begins three seconds
             after the Storyboard begins (total of 5 seconds)-->
        <DoubleAnimation BeginTime="0:0:3"
          Storyboard.TargetName="MyAnimatedRectangle" 
          Storyboard.TargetProperty="Opacity"
          To="0" Duration="0:0:1" />

The first animation starts as soon as the Storyboard starts and lasts 1 second. The second animations starts 3 seconds after the Storyboard starts and also lasts 1 second.

So in your example you'd set the duration of the animation that fades the popup to 2 seconds (say):

<DoubleAnimation Duration="0:0:2" To="0"
                 Storyboard.TargetProperty="(UIElement.Opacity)"
                 Storyboard.TargetName="Popup" d:IsOptimized="True"/>

and then set the begin time of the animation that sets the visibility to 2 seconds:

        <ObjectAnimationUsingKeyFrames BeginTime="0:0:2"
                         Storyboard.TargetProperty="(UIElement.Visibility)"
                         Storyboard.TargetName="Popup">
            <DiscreteObjectKeyFrame KeyTime="0">
                <DiscreteObjectKeyFrame.Value>
                    <Visibility>Collapsed</Visibility>
                </DiscreteObjectKeyFrame.Value>
            </DiscreteObjectKeyFrame>
        </ObjectAnimationUsingKeyFrames>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top