简体   繁体   English

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

[英]Rotation Animation for ItemTemplate in GridView - C# - UWP

I have a GridView in my app which has a Template and this Template includes a couple of TextBlock items and an Image inside a StackPanel . 我的应用程序中有一个GridView ,它具有一个Template并且此TemplateStackPanel包含几个TextBlock项和一个Image I want to Rotate the StackPanel in Z axis (preferably, as you can say vertically - not in circular way - as in Sims 3 you can rotate a character) ( correct me if I am wrong and it is not Z axis. ) but I am not able to do that since Template part of the GridView cannot be accessed from outside the template. 我想在Z轴上旋转StackPanel (最好,如您所说的那样,垂直而不是圆形-就像在Sims 3中一样,您可以旋转一个字符)( 如果我错了,请纠正我,它不是Z轴。 )但是我之所以无法做到这一点,是因为无法从模板外部访问GridView Template部分。 So the DoubleAnimation returns an error that the name of the element was not found. 因此, DoubleAnimation返回一个错误,即找不到元素的名称。 I even tried to set the target to the Title of my ItemsClass for my Template but still it says the name was not found. 我什至尝试将目标设置为我的Template的ItemsClassTitle ,但仍然说找不到该名称。

So is there anyway to achieve this? 那么有什么办法可以做到这一点? I am trying the following code for now. 我现在正在尝试以下代码。

Favorites.xaml 收藏夹.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 收藏夹.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 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; }
  }
}

This is only the relevant part (of the entire code) that corresponds to the animation. 这只是(整个代码中的)与动画相对应的相关部分。

According to your description, it seems you want to rotate the StackPanel when pointer entered. 根据您的描述,似乎您想在输入指针时旋转StackPanel If so, you can try with following code: 如果是这样,您可以尝试以下代码:

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

Here we should use Storyboard.SetTarget method instead of Storyboard.SetTargetName method as your StackPanel in DataTemplate and there will be a lot of StackPanel s with the same name when the GridView loaded. 在这里,我们应该使用Storyboard.SetTarget方法而不是Storyboard.SetTargetName方法作为DataTemplateStackPanel ,并且在加载GridView时,会有很多具有相同名称StackPanel

Besides this, we also need to stop current animation when pointer moving into other StackPanel . 除此之外,当指针移至其他StackPanel时,我们还需要停止当前动画。 If not, we might get error like: 如果没有,我们可能会收到如下错误:

Operation is not valid on an active Animation or Storyboard. 操作在活动的动画或情节提要板上无效。 Root Storyboard must be stopped first. 根故事板必须首先停止。

So I defined a CurrentTarget field to store current target StackPanel . 因此,我定义了一个CurrentTarget字段来存储当前目标StackPanel

At last, you may also need to modify RotateAnimation as RepeatBehavior="1" specifies one day which is not logical to me and to specifies one time we should use RepeatBehavior="1x" . 最后,您可能还需要修改RotateAnimation因为RepeatBehavior="1"指定了一天 ,这对我来说不合逻辑,并指定了一次我们应该使用RepeatBehavior="1x" For more info, please see XAML Values of RepeatBehavior structure . 有关更多信息,请参见RepeatBehavior结构的 XAML值

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM