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