Question

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?

Was it helpful?

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();
    }

OTHER TIPS

This doesn't seem like a sensible thing to want to do, and a grid animation like this is going to look awful because it's not on the compositor, but:

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

private void grid1_Tap(object sender, RoutedEventArgs e)
{
    double fromHeight = this.LayoutRoot.RowDefinitions[2].ActualHeight;

    this.LayoutRoot.RowDefinitions[2].Height = new GridLength(3, GridUnitType.Star);
    this.LayoutRoot.Measure(new Size(this.Width, this.Height));

    double toHeight = this.LayoutRoot.RowDefinitions[2].DesiredSize.Height;

    MyStoryboard.From = fromHeight;
    MyStoryboard.To = toHeight;
    MyStoryboard.Begin();
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top