Search code examples
xamlexpression-blend

How to animate appearing of an element


I have an question about Expression Blend 4.

I want to create a simple component appearing animation, when height of component changes from 0 to 100% and components below it are moving down to allocate required space.

My problem is that only static values in pixels allowed to create such type of animation. But I did not know height of my control (actually, it is textBox in which content and content length may vary), and I cannot set Height value of last keyframe to Auto.

What should I do to implement this task?

Thanks in advance.


Solution

  • I guess the easist way would be using the Fluid Layout.

    In the below example I created a TextBlock and set its Visibility to Collpased. Then when the Show visual state is triggered, I set its Visibility to Visible. Normally you can't animate the Visibility but if you enable the Fluid Layout behavior (also remember to define a TransitionEffect), it will animate it for you automatically.

    enter image description here

    <UserControl
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" xmlns:ee="http://schemas.microsoft.com/expression/2010/effects" xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" mc:Ignorable="d"
        x:Class="transformanimation.MainPage"
        Width="640" Height="480">
        <UserControl.Resources>
            <Storyboard x:Name="Storyboard1">
                <DoubleAnimation Duration="0:0:0.7" To="0.2" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleX)" Storyboard.TargetName="textBlock" d:IsOptimized="True"/>
                <DoubleAnimation Duration="0:0:0.7" To="0.2" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleY)" Storyboard.TargetName="textBlock" d:IsOptimized="True"/>
            </Storyboard>
        </UserControl.Resources>
    
        <Grid x:Name="LayoutRoot" Background="White">
            <VisualStateManager.VisualStateGroups>
                <VisualStateGroup x:Name="VisualStateGroup" ei:ExtendedVisualStateManager.UseFluidLayout="True">
                    <VisualStateGroup.Transitions>
                        <VisualTransition GeneratedDuration="0:0:0.2">
                            <ei:ExtendedVisualStateManager.TransitionEffect>
                                <ee:FadeTransitionEffect/>
                            </ei:ExtendedVisualStateManager.TransitionEffect>
                        </VisualTransition>
                    </VisualStateGroup.Transitions>
                    <VisualState x:Name="Hide"/>
                    <VisualState x:Name="Show">
                        <Storyboard>
                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="textBlock">
                                <DiscreteObjectKeyFrame KeyTime="0">
                                    <DiscreteObjectKeyFrame.Value>
                                        <Visibility>Visible</Visibility>
                                    </DiscreteObjectKeyFrame.Value>
                                </DiscreteObjectKeyFrame>
                            </ObjectAnimationUsingKeyFrames>
                        </Storyboard>
                    </VisualState>
                </VisualStateGroup>
            </VisualStateManager.VisualStateGroups>
            <VisualStateManager.CustomVisualStateManager>
                <ei:ExtendedVisualStateManager/>
            </VisualStateManager.CustomVisualStateManager>
            <Grid Margin="205,96,275,150">
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition/>
                </Grid.RowDefinitions>
                <TextBlock x:Name="textBlock" TextWrapping="Wrap" Text="TextBlock" FontSize="26.667" RenderTransformOrigin="0.5,0.5" Visibility="Collapsed">
                    <TextBlock.RenderTransform>
                        <CompositeTransform/>
                    </TextBlock.RenderTransform>
                </TextBlock>
                <Rectangle Fill="#FF767689" Stroke="Black" Grid.Row="1"/>
            </Grid>
            <Button Content="hide" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Margin="63,19,0,0">
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="Click">
                        <ei:GoToStateAction StateName="Hide"/>
                    </i:EventTrigger>
                </i:Interaction.Triggers>
            </Button>
            <Button Content="show" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Margin="183,20,0,0">
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="Click">
                        <ei:GoToStateAction StateName="Show"/>
                    </i:EventTrigger>
                </i:Interaction.Triggers>
            </Button>
        </Grid>
    </UserControl>
    

    Of course if you don't want to use this magicial animation you can try animating its ScaleY. Something like this,

            <DoubleAnimation Duration="0:0:0.2" To="0" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleY)" Storyboard.TargetName="textBlock" d:IsOptimized="True"/>
    

    Hope this helps! :)