我有一个 LongListSelector,其中填充了一些项目。每个项目都有一个子菜单,可以使用滑动动画显示或折叠该子菜单。问题是动画非常慢,具体取决于您在列表中点击的项目。开始和结束的时候很慢,中间很顺利。我怀疑每个动画帧都会使长列表选择器无效,这意味着整个可视化树必须更新其布局。
我使用数据触发器来启动动画。因此,我可以看到许多其他项目上的触发器也被触发,这表明它们正在被重新绘制。它还表明,当您点击列表中间时,触发的其他项目也会少得多。诡异的...
我在github上托管了测试项目:https://github.com/jessetabak/wpanimationproblem https://github.com/jessetabak/wpanimationproblem
长列表选择器:
<phone:LongListSelector x:Name="LongList" Margin="0" Padding="0" ItemsSource="{Binding Items}"
HorizontalAlignment="Stretch" Background="Transparent">
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<wegGooiApp2:ItemView />
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>
项目视图:
<UserControl.Resources>
<wegGooiApp2:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" />
<Storyboard x:Key="ShowMenu">
<DoubleAnimation Storyboard.TargetProperty="(Grid.Height)"
Storyboard.TargetName="Submenu"
From="0" To="70" Duration="0:0:0.25" />
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Submenu"
Storyboard.TargetProperty="(Grid.Visibility)">
<DiscreteObjectKeyFrame KeyTime="0:0:0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="HideMenu">
<DoubleAnimation Storyboard.TargetProperty="(Grid.Height)"
Storyboard.TargetName="Submenu"
From="70" To="0" Duration="0:0:0.25" />
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Submenu"
Storyboard.TargetProperty="(Grid.Visibility)">
<DiscreteObjectKeyFrame KeyTime="0:0:0.25">
<DiscreteObjectKeyFrame.Value>
<Visibility>Collapsed</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!-- TEST ITEM -->
<Border Height="70" BorderBrush="Red" Background="Transparent" BorderThickness="1" HorizontalAlignment="Stretch">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Text="Test Item" HorizontalAlignment="Stretch" FontSize="42" />
<Button Content="v" Grid.Column="1" Tap="Button_Tap" Tag="{Binding}">
</Button>
</Grid>
</Border>
<!-- SUBMENU -->
<Border x:Name="Submenu" Grid.Row="1" BorderBrush="Green" BorderThickness="1"
Visibility="{Binding SubMenuIsVisible, Converter={StaticResource BoolToVisibilityConverter}, Mode=OneTime}"
Background="Green" Height="0" Margin="0 0 0 0">
<i:Interaction.Triggers>
<ec:DataTrigger Binding="{Binding SubMenuIsVisible}" Value="True">
<ec:CallMethodAction MethodName="MenuEnabled"
TargetObject="{Binding ElementName=ThisUserControl, Mode=OneWay}" />
</ec:DataTrigger>
<ec:DataTrigger Binding="{Binding SubMenuIsVisible}" Value="False">
<ec:CallMethodAction MethodName="MenuDisabled"
TargetObject="{Binding ElementName=ThisUserControl, Mode=OneWay}" />
</ec:DataTrigger>
</i:Interaction.Triggers>
<TextBlock Text="SubMenu" FontSize="42" />
</Border>
</Grid>
</UserControl>
ItemView 代码隐藏:
public partial class ItemView : UserControl
{
private Storyboard _showStoryboard;
private Storyboard _hideStoryboard;
public ItemView()
{
InitializeComponent();
_showStoryboard = (Storyboard) this.Resources["ShowMenu"];
_hideStoryboard = (Storyboard) this.Resources["HideMenu"];
Debug.WriteLine("ItemView CONSTRUCTED");
}
private void Button_Tap(object sender, GestureEventArgs e)
{
var button = (Button)sender;
var viewModelItem = (ItemViewModel)button.Tag;
viewModelItem.SubMenuIsVisible = !viewModelItem.SubMenuIsVisible;
}
public void MenuEnabled()
{
Debug.WriteLine("MENU ENABLED!");
if (Submenu.Visibility == Visibility.Collapsed)
{
_showStoryboard.Begin();
}
}
public void MenuDisabled()
{
Debug.WriteLine("MENU DISABLED!");
if (Submenu.Visibility == Visibility.Visible)
{
_hideStoryboard.Begin();
}
}
private void ThisUserControl_LayoutUpdated(object sender, EventArgs e)
{
//Debug.WriteLine("ITEMVIEW LAYOUT UPDATED!");
}
}
它看起来像什么:
/edit 1
我尝试使用 ScaleTransform 将其转换为独立动画,但这不会为周围的 ui 元素设置动画。要解决此问题,您可以使用布局变换 http://blogs.msdn.com/b/delay/archive/2010/08/26/your-phone-can-turn-into-a-robot-layouttransformer-works-great-on-the-windows-phone-platform.aspx?CommentPosted=true#commentmessage而不是标准的 RenderTransform。经过一些调整后,效果非常好,但是布局变换以缓慢的依赖动画将其返回......