Reputation: 1959
I'm trying to create a simple animation where a grid animates from 0 height to a set value of 320. (which will give a slide-feeling), whilst also animating the opacity from 0-1 and back.
I created two storyboards and gave them a name, here are they:
<Page.Resources>
<Storyboard x:Name="OpenSettings" Storyboard.TargetName="SettingGrid">
<DoubleAnimation Storyboard.TargetProperty="Height" Storyboard.TargetName="SettingGrid" To="320"/>
<DoubleAnimation Storyboard.TargetProperty="Opacity" Storyboard.TargetName="SettingGrid" To="1"/>
</Storyboard>
<Storyboard x:Name="CloseSettings">
<DoubleAnimation Storyboard.TargetProperty="Height" Storyboard.TargetName="SettingGrid" To="0"/>
<DoubleAnimation Storyboard.TargetProperty="Opacity" Storyboard.TargetName="SettingGrid" To="0"/>
</Storyboard>
</Page.Resources>
And I try to run the animations from code-behind, like this:
private void AppBarButton_Click(object sender, RoutedEventArgs e)
{
if (settingsOpened)
{
CloseSettings.Begin();
settingsOpened = false;
}
else
{
OpenSettings.Begin();
settingsOpened = true;
}
}
bool settingsOpened = false;
The problem is at the Height-doubleanimation. It isn't changing any height value on the Grid. The Opacity animation is working great by the way.
Does anyone know how I might be able to solve this?
Here is the Grid I'm trying to animate, too. Notice how I have set fixed start-values which makes the "from" property in the animations unnecessary.
<Grid Opacity="1" Height="0" VerticalAlignment="Top" Name="SettingGrid" Background="#151515">
<CheckBox Margin="10,0,0,0" Content="Use front camera" Height="80"/>
<TextBlock Text="IP Address" Margin="10,70,10,0" FontSize="25" FontWeight="Light" Height="30" VerticalAlignment="Top"/>
<TextBox Text="127.0.0.1" Margin="10,100,10,0" Height="40" VerticalAlignment="Top" Name="IPBox"/>
<TextBlock Text="Port" Margin="10,150,10,0" FontSize="25" FontWeight="Light" Height="30" VerticalAlignment="Top"/>
<TextBox Text="12345" Margin="10,180,10,0" Height="40" VerticalAlignment="Top" Name="PortBox"/>
<Slider Margin="10,230,10,0" Height="45" VerticalAlignment="Top" Name="updateFreq" Value="20"/>
<StackPanel Margin="10,270,0,0" Orientation="Horizontal">
<TextBlock FontSize="25" VerticalAlignment="Top" Margin="10,0,0,0" FontWeight="Light" HorizontalAlignment="Left" Text="{Binding ElementName=updateFreq, Path=Value}"/>
<TextBlock Text=" Times per second" FontSize="25" FontWeight="Light" VerticalAlignment="Top"/>
</StackPanel>
</Grid>
As I said, why isn't the animation doing anything to the height?
Upvotes: 1
Views: 1041
Reputation: 21919
Instead of animating Height add a RenderTransform to the SettingGrid and animate it to ScaleTransform.ScaleY from 0 to 1.0. Another option would be to use one of the in-box personality transitions rather than a custom animation (See Quickstart: Animating your UI using library animations (XAML))
Animating Height affects the layout of the scene and requires synchronizing with the main UI thread. This is called a "dependant animation". Animating the RenderTransform will give a very similar effect but won't require additional layout passes and can run fully on the rendering thread. This is called an "independent animation".
Independent animations are preferred whenever possible. Dependent animations should be avoided and are disabled by default. If you really want to stick with animating the Height property then you need to set the EnableDependentAnimation property to true.
This scenario (Height vs. RenderTransform Scale) is the example used in the Make animations smooth (XAML) documentation.
Blend is a great too to set up your animations. Here's a quick example. Blend prefers a CompositeTransform since it's more flexible. If you know you only need scaling then you can use a ScaleTransform. You can change the RenderTransformOrigin to 0.5,0.0 if you want it to open from the top rather than the middle.
<Page.Resources>
<Storyboard x:Name="OpenSettings">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleY)" Storyboard.TargetName="SettingGrid">
<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
<EasingDoubleKeyFrame KeyTime="0:0:1" Value="1"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="SettingGrid">
<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
<EasingDoubleKeyFrame KeyTime="0:0:1" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Page.Resources>
<Grid x:Name="SettingGrid" Background="{StaticResource ApplicationPageBackgroundThemeBrush}" RenderTransformOrigin="0.5,0.5">
<Grid.RenderTransform>
<CompositeTransform/>
</Grid.RenderTransform>
</Grid>
Upvotes: 5
Reputation: 680
Try setting From values in the DoubleAnimation(s) e.g:
<Storyboard x:Name="OpenSettings" Storyboard.TargetName="SettingGrid">
<DoubleAnimation Storyboard.TargetProperty="Height" Storyboard.TargetName="SettingGrid" From="0" To="320"/>
<DoubleAnimation Storyboard.TargetProperty="Opacity" Storyboard.TargetName="SettingGrid" To="1"/>
</Storyboard>
<Storyboard x:Name="CloseSettings">
<DoubleAnimation Storyboard.TargetProperty="Height" Storyboard.TargetName="SettingGrid" From="320" To="0"/>
<DoubleAnimation Storyboard.TargetProperty="Opacity" Storyboard.TargetName="SettingGrid" To="0"/>
</Storyboard>
Edit: Using '(FrameworkElement.Height)' instead
<Storyboard x:Name="OpenSettings" Storyboard.TargetName="SettingGrid">
<DoubleAnimation Storyboard.TargetProperty="(FrameworkElement.Height)" Storyboard.TargetName="SettingGrid" To="320"/>
<DoubleAnimation Storyboard.TargetProperty="Opacity" Storyboard.TargetName="SettingGrid" To="1"/>
</Storyboard>
<Storyboard x:Name="CloseSettings">
<DoubleAnimation Storyboard.TargetProperty="(FrameworkElement.Height)" Storyboard.TargetName="SettingGrid" To="0"/>
<DoubleAnimation Storyboard.TargetProperty="Opacity" Storyboard.TargetName="SettingGrid" To="0"/>
</Storyboard>
Upvotes: 0