GridView 中 ItemTemplate 的旋转动画 - C# - UWP

Rotation Animation for ItemTemplate in GridView - C# - UWP

我的应用程序中有一个 GridView,它有一个 Template,这个 Template 包括几个 TextBlock 项和一个 Image StackPanel。我想在 Z 轴上旋转 StackPanel(最好是垂直方向 - 而不是圆形方式 - 就像在模拟人生 3 中一样,你可以旋转一个角色)( 如果我错了请纠正我,它不是 Z 轴。) 但我无法这样做,因为无法从模板外部访问 GridView 的模板部分。所以 DoubleAnimation returns 一个错误,即找不到元素的名称。我什至尝试将目标设置为我的模板的 ItemsClassTitle,但它仍然说找不到名称。

那么有什么方法可以做到这一点吗? 我现在正在尝试以下代码。

Favorites.xaml

<GridView ItemsSource="{x:Bind TVFavoritesList, Mode=OneWay}"
                      x:Name="TVDataGrid"
                      HorizontalAlignment="Left"
                      Height="350"
                      Margin="10"
                      IsItemClickEnabled="True"
                      ItemClick="dataGrid_ItemClick"
                      ScrollViewer.HorizontalScrollMode="Auto"
                      ScrollViewer.HorizontalScrollBarVisibility="Auto"
                      ScrollViewer.VerticalScrollMode="Disabled">
                <GridView.Header>
                    <TextBlock Text=""
                               x:Name="TVFavoritesHeader"
                               VerticalAlignment="Center"
                               TextAlignment="Center"
                               Margin="5,0"/>
                </GridView.Header>
                <GridView.HeaderTransitions>
                    <TransitionCollection>
                        <EdgeUIThemeTransition/>
                    </TransitionCollection>
                </GridView.HeaderTransitions>
                <GridView.ItemsPanel>
                    <ItemsPanelTemplate>
                        <ItemsWrapGrid Orientation="Vertical" />
                    </ItemsPanelTemplate>
                </GridView.ItemsPanel>
                <GridView.ItemContainerTransitions>
                    <TransitionCollection>
                        <PaneThemeTransition Edge="Top"/>
                    </TransitionCollection>
                </GridView.ItemContainerTransitions>
                <GridView.ItemTemplate>
                    <DataTemplate x:DataType="data:ItemsClass">
                        <StackPanel Margin="0,10,10,10"
                                    Name="rotateme"
                                    HorizontalAlignment="Center"
                                    BorderBrush="Red"
                                    BorderThickness="0,1"
                                    IsRightTapEnabled="True"
                                    PointerEntered="TVItemPanel_PointerEntered"
                                    RightTapped="ItemPanel_RightTapped">
                            <TextBlock x:Name="Title"
                                        Text="{x:Bind ItemTitle, Mode=OneWay}"
                                        TextAlignment="Center"
                                        TextWrapping="Wrap"
                                        Height="40"
                                        Width="200"/>
                            <Image x:Name="CoverImage"
                                    Source="{x:Bind ItemImageLink, Mode=OneWay}"
                                    Width="180"
                                    Height="250"
                                    Margin="0"/>
                            <Image Source="ms-appx:///Assets/newcontent.png"
                                   HorizontalAlignment="Center"
                                   Visibility="{x:Bind ItemUpdate, Mode=OneWay}"
                                   Width="150"
                                   Margin="0,-250,0,0"/>
                            <TextBlock Text="{x:Bind ItemType, Mode=OneWay}"
                                        TextAlignment="Center"
                                        TextWrapping="Wrap"/>
                            <StackPanel.RenderTransform>
                                <RotateTransform/>
                            </StackPanel.RenderTransform>
                        </StackPanel>
                    </DataTemplate>
                </GridView.ItemTemplate>
</GridView>


<Page.Resources>
<Storyboard x:Name="AnimationStoryboard">
<DoubleAnimation x:Name="RotateAnimation" To="360" RepeatBehavior="1"
Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)">
</DoubleAnimation>
</Storyboard>
</Page.Resources>

Favorites.xaml.cs

private void TVItemPanel_PointerEntered(object sender, PointerRoutedEventArgs e)
{
        var pointer = (StackPanel)sender;
        var item = (ItemsClass)((FrameworkElement)e.OriginalSource).DataContext;
        Storyboard.SetTargetName(RotateAnimation, pointer.Name);
        //Storyboard.SetTargetName(RotateAnimation, item.ItemTitle);
        AnimationStoryboard.Begin();
}

ItemsClass.cs

namespace WatchfreeWebsite
{
public class ItemsClass
  {

    public int ItemID
    { get; set; }

    public string ItemTitle
    { get; set; }

    public string ItemType
    { get; set; }

    public string ItemImageLink
    { get; set; }

    public string ItemPageLink
    { get; set; }

    public Visibility ItemUpdate
    { get; set; }
  }
}

这只是与动画对应的(整个代码的)相关部分。

根据您的描述,您似乎希望在指针进入时旋转 StackPanel。如果是这样,您可以尝试使用以下代码:

private StackPanel CurrentTarget;

private void TVItemPanel_PointerEntered(object sender, PointerRoutedEventArgs e)
{
    var pointer = (StackPanel)sender;
    if (AnimationStoryboard.GetCurrentState() == ClockState.Active && CurrentTarget.Equals(pointer))
    {
        return;
    }
    else
    {
        AnimationStoryboard.Stop();

        Storyboard.SetTarget(RotateAnimation, pointer);

        AnimationStoryboard.Begin();
        CurrentTarget = pointer;
    }
}

这里我们应该使用Storyboard.SetTarget method instead of Storyboard.SetTargetName方法作为你在DataTemplate中的StackPanel并且会有很多StackPanel同名GridView 加载时。

除此之外,我们还需要在指针移动到其他地方时停止当前动画StackPanel。如果不是,我们可能会得到类似这样的错误:

Operation is not valid on an active Animation or Storyboard. Root Storyboard must be stopped first.

所以我定义了一个CurrentTarget字段来存储当前目标StackPanel

最后,你可能还需要修改RotateAnimation因为RepeatBehavior="1"指定一天这对我来说不合逻辑并且指定一次我们应该使用RepeatBehavior="1x"。有关详细信息,请参阅 RepeatBehavior structureXAML 值