【问题标题】:Animate grid row height change in WPWP中的动画网格行高变化
【发布时间】:2013-07-27 08:32:35
【问题描述】:

我想为网格行高度变化设置动画,但是如何使用动态“星形”高度值来实现呢?

我有以下网格:

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

【问题讨论】:

  • 问题不清楚。 “grid3 被隐藏”,但您的 XAML 中没有定义“grid3”。
  • 抱歉,混淆了网格名称。固定...

标签: windows-phone-8 grid storyboard animated


【解决方案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();
    }

【讨论】:

  • 这里的问题是我想使用动态缩放,让应用程序在所有手机分辨率下工作。基本上在第一个元素(grid0)中有地图控制器,第二个(grid1)包含文本框,最后一个(grid2)有longListSelector。要使上面的示例正常工作,我需要为边框元素指定确切的高度尺寸。但是如何在不同的屏幕分辨率下处理呢?
  • 谢谢 Rob,但我认为 Windows Phone 不支持 BeginAnimation?至少当我尝试将它与 longListSelector 或 map 一起使用时,我收到错误...不包含 'BeginAnimation' 的定义。
  • 你是对的;这在 WP8 SDK 中是缺失的。但是你的帖子上有一个 WPF 标签,所以我认为这将是一个令人满意的答案。希望这个对你有用。查看修改。
  • 嗯,在这个例子中,我可以很好地隐藏 ListBox,但我认为我需要设置网格行定义高度。现在 ListBox 被隐藏了,网格行定义保持不变,顶部的地图控件没有展开,即使 ListBox 也被隐藏了。
  • GridLength 的动画类不存在。
【解决方案2】:

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

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

【讨论】:

  • 任何其他想法如何处理类似的功能?我也可以使用除网格之外的任何其他控件。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-07
  • 1970-01-01
  • 2022-01-19
  • 2015-02-27
  • 1970-01-01
  • 2018-09-13
相关资源
最近更新 更多