首页 > 解决方案 > 有没有办法将 Storyboard 与 ListView/GridView 项目一起使用?

问题描述

这是我的问题:

  1. 我的 UWP 应用中有一个 GridView。GridView 中的每个项目都保留一个按钮。如下:
<GridView ItemsSource="{x:Bind ExampleItems, Mode=OneWay}" x:Name="mDataGridView">
    <GridView.ItemTemplate>
        <DataTemplate x:Name="DataTemplate" x:DataType="local:ItemTemplate">
            <StackPanel Height="100" Width="100" Background="OrangeRed" x:Name="rootPanel">
                <Grid Width="155" Height="210" Background="Red" x:Name="myGrid"/>
                <Button x:Name="mOpenDetailButton" Click="mOpenDetailButton_Click" Margin="0, 30, 20,0"/>
            </StackPanel>
        </DataTemplate>
    </GridView.ItemTemplate>
</GridView>
  1. 我在故事板中也有一个预定义的动画,如下所示
<Storyboard x:Name="OpenStoryboard">
    <DoubleAnimationUsingKeyFrames Storyboard.TargetName="grid" x:Name="mOpenAnimation" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleY)">
        <EasingDoubleKeyFrame KeyTime="00:00:00" Value="0.095"/>
        <EasingDoubleKeyFrame KeyTime="00:00:00.1" Value="1"/>
    </DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Name="CloseStoryboard">
    <DoubleAnimation Storyboard.TargetName="grid" Duration="00:00:00.1" x:Name="mCloseAnimation" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleY)" To="0.095"/>
</Storyboard>

好的,问题来了,是否可以将 Storyboards 中定义的动画与 GridView 项目一起使用?我想要的是:当用户单击 mOpenDetailButton 按钮时,将播放 OpenStoryboard,并且网格的 ScaleY 值随之变化。

任何帮助将不胜感激,谢谢。

标签: c#uwp

解决方案


您可以将 Storyboard 放在 DataTemplate 内的 StackPanel 中,并在 myGrid 上定义一个 RenderTransform 作为 StackPanel 的目标对象。在这种情况下,它简化了目标对象的规范,并且更方便地在代码隐藏中获取 Storyboard 并进行播放。例如:

.xaml:

<GridView ItemsSource="{x:Bind ExampleItems, Mode=OneWay}" x:Name="mDataGridView">
    <GridView.ItemTemplate>
        <DataTemplate x:Name="DataTemplate" x:DataType="local:ItemTemplate">
            <StackPanel Height="100" Width="100" Background="OrangeRed" x:Name="rootPanel">
                <StackPanel.Resources>
                    <Storyboard x:Name="OpenStoryboard">
                        <DoubleAnimationUsingKeyFrames 
                            Duration="0:0:0.2"
                            Storyboard.TargetProperty="ScaleY"
                            Storyboard.TargetName="transform" >
                            <EasingDoubleKeyFrame KeyTime="00:00:00" Value="0.095"/>
                            <EasingDoubleKeyFrame KeyTime="00:00:00.1" Value="1"/>
                        </DoubleAnimationUsingKeyFrames>
                    </Storyboard>
                </StackPanel.Resources>
                <Grid Width="100" Height="50" Background="Red" x:Name="myGrid">
                    <Grid.RenderTransform>
                        <CompositeTransform
                            x:Name="transform"
                            ScaleX="1" ScaleY="0" />
                    </Grid.RenderTransform>
                </Grid>

                <Button x:Name="mOpenDetailButton" Content="Mybutton" Click="mOpenDetailButton_Click" Margin="20"/>
            </StackPanel>
        </DataTemplate>
    </GridView.ItemTemplate>
</GridView>

。CS:

首先,通过按钮获取其父面板(StackPanel),然后获取其故事板动画并播放。

private void mOpenDetailButton_Click(object sender, RoutedEventArgs e)
{
    UIElement mybutton = sender as UIElement;
    StackPanel stackPanel = FindParent<StackPanel>(mybutton);
    object storyvalue = null;
    stackPanel?.Resources.TryGetValue("OpenStoryboard", out storyvalue);
    Storyboard storyboard = value as Storyboard;
    storyboard?.Begin();
}

public static T FindParent<T>(DependencyObject element)
            where T : DependencyObject
{
    while (element != null)
    {
        DependencyObject parent = VisualTreeHelper.GetParent(element);
        T candidate = parent as T;
        if (candidate != null)
        {
            return candidate;
        }
        element = parent;
    }
    return default(T);
}

推荐阅读