Search code examples
windows-phone-8gridstoryboardanimated

Animate grid row height change in WP


I want to animate the grid row height change, but how to do that with dynamic "star" height values?

I have the following grid:

<Grid x:Name="baseGrid">
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="3*"/>
    </Grid.RowDefinitions>
    <Grid x:Name="grid0" Grid.Row="0" Tap="grid0_Tap">
        // Content
    </Grid>
    <Grid x:Name="grid1" Grid.Row="1" Tap="grid1_Tap">
        // Content
    </Grid>
    <Grid x:Name="grid2" Grid.Row="2">
        // Content
    </Grid>
</Grid>

In code behind I have logic that if user clicks grid0, grid2 gets hidden. Again if user click grid1, grid2 gets its size back.

private void grid0_Tap(object sender, RoutedEventArgs e)
{
    this.LayoutRoot.RowDefinitions[2].Height = new GridLength(0);
}

private void grid1_Tap(object sender, RoutedEventArgs e)
{
    this.LayoutRoot.RowDefinitions[2].Height = new GridLength(3, GridUnitType.Star);
}

This works well right now, but how to animate this? I think Storyboard needs its from/to value and as Im using dynamic sizes I can not use Storyboard?


Solution

  • (EDITED to address the Windows Phone 8 animation storyboard question)

    An animation class for GridLength doesn't exist in any XAML library.

    But you can get close, or you can turn to third-party controls which do what you want.

    And, for this use case, code-behind is pretty much required, instead of defining a XAML resource, since you're discovering the ActualHeight of the element at run-time:

    private double storedHeight = 0.0;
        private void grid0_Tap(object sender, System.Windows.Input.GestureEventArgs e)
        {
            //ListBox1.Visibility = Visibility.Visible; 
            if (storedHeight == 0.0) return;
            var d = new DoubleAnimation();
            d.From = 0.0;
            d.To = storedHeight;
            d.Duration = TimeSpan.FromMilliseconds(200);
            storedHeight = 0.0;
            var s = new Storyboard();
            Storyboard.SetTarget(d, grid2);
            Storyboard.SetTargetProperty(d, new PropertyPath("Height"));
            s.Children.Add(d);
            s.Begin();
    
        }
    
        private void grid1_Tap(object sender, System.Windows.Input.GestureEventArgs e)
        {
            //ListBox1.Visibility = Visibility.Hidden;
            if (storedHeight > 0.0) return;
            storedHeight = ListBox1.ActualHeight;
            var d = new DoubleAnimation();
            d.From = storedHeight;
            d.To = 0.0;
            d.Duration = TimeSpan.FromMilliseconds(200);
    
            var s = new Storyboard();
            Storyboard.SetTarget(d, grid2);
            Storyboard.SetTargetProperty(d, new PropertyPath("Height"));
            s.Children.Add(d);
            s.Begin();
        }