1

我想为网格行高度变化设置动画,但是如何使用动态“星形”高度值来做到这一点?

我有以下网格:

<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>

在后面的代码中,我有逻辑,如果用户单击 grid0,grid2 会被隐藏。同样,如果用户单击 grid1,grid2 会恢复其大小。

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

现在效果很好,但是如何制作动画呢?我认为 Storyboard 需要它的 from/to 值,因为我使用动态尺寸我不能使用 Storyboard?

4

2 回答 2

1

(编辑以解决 Windows Phone 8 动画故事板问题)

GridLength任何 XAML 库中都不存在的动画类。

但是你可以接近,或者你可以求助于第三方控件来做你想做的事。

而且,对于这个用例,几乎需要代码隐藏,而不是定义 XAML 资源,因为您在运行时发现了元素的 ActualHeight:

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();
    }
于 2013-07-29T03:41:18.280 回答
0

这似乎不是一件明智的事情,像这样的网格动画看起来很糟糕,因为它不在合成器上,但是:

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();
}
于 2013-07-27T01:25:01.540 回答