title: Slow storyboard animation inside LongListSelector
body: <p>I have a LongListSelector which is populated with some items. Each item has a submenu which can be visible or collapsed using a sliding animation. The problem is that the animation is extremely slow depending on which item you tap in the list. At the start and the end it's slow, in the middle it's smooth. I suspect that each animation frame invalidates the longlistselector which means the entire visual tree must update it's layout.</p>
  
  <p>I use a datatrigger to start the animation. Because of that I can see that the triggers on lots of other items also get fired which indicates to me they are being redrawn. It also shows that when you tap in the middle of list a lot less other items get triggered as well. weird...</p>
  
  <p>I hosted the testproject on github:
  <a href="https://github.com/jessetabak/wpanimationproblem" rel="nofollow noreferrer">https://github.com/jessetabak/wpanimationproblem</a></p>
  
  <p>The LongListSelector:</p>
  
  <pre><code>&lt;phone:LongListSelector x:Name="LongList" Margin="0" Padding="0" ItemsSource="{Binding Items}" 
          HorizontalAlignment="Stretch" Background="Transparent"&gt;
      &lt;phone:LongListSelector.ItemTemplate&gt;
          &lt;DataTemplate&gt;
              &lt;wegGooiApp2:ItemView /&gt;
          &lt;/DataTemplate&gt;
      &lt;/phone:LongListSelector.ItemTemplate&gt;
  
  &lt;/phone:LongListSelector&gt;
  </code></pre>
  
  <p>The ItemView:</p>
  
  <pre><code>&lt;UserControl.Resources&gt;
  
          &lt;wegGooiApp2:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" /&gt;
  
          &lt;Storyboard x:Key="ShowMenu"&gt;
              &lt;DoubleAnimation Storyboard.TargetProperty="(Grid.Height)" 
                               Storyboard.TargetName="Submenu"
                               From="0" To="70" Duration="0:0:0.25" /&gt;
  
              &lt;ObjectAnimationUsingKeyFrames Storyboard.TargetName="Submenu"
                                             Storyboard.TargetProperty="(Grid.Visibility)"&gt;
                  &lt;DiscreteObjectKeyFrame KeyTime="0:0:0"&gt;
                      &lt;DiscreteObjectKeyFrame.Value&gt;
                          &lt;Visibility&gt;Visible&lt;/Visibility&gt;
                      &lt;/DiscreteObjectKeyFrame.Value&gt;
                  &lt;/DiscreteObjectKeyFrame&gt;
              &lt;/ObjectAnimationUsingKeyFrames&gt;
  
          &lt;/Storyboard&gt;
  
          &lt;Storyboard x:Key="HideMenu"&gt;       
  
              &lt;DoubleAnimation Storyboard.TargetProperty="(Grid.Height)"
                              Storyboard.TargetName="Submenu"
                              From="70" To="0" Duration="0:0:0.25" /&gt;
  
              &lt;ObjectAnimationUsingKeyFrames Storyboard.TargetName="Submenu"
                                             Storyboard.TargetProperty="(Grid.Visibility)"&gt;
                  &lt;DiscreteObjectKeyFrame KeyTime="0:0:0.25"&gt;
                      &lt;DiscreteObjectKeyFrame.Value&gt;
                          &lt;Visibility&gt;Collapsed&lt;/Visibility&gt;
                      &lt;/DiscreteObjectKeyFrame.Value&gt;
                  &lt;/DiscreteObjectKeyFrame&gt;
              &lt;/ObjectAnimationUsingKeyFrames&gt;
  
          &lt;/Storyboard&gt;        
  
      &lt;/UserControl.Resources&gt;
  
      &lt;Grid x:Name="LayoutRoot" Background="Transparent"&gt;
          &lt;Grid.RowDefinitions&gt;
              &lt;RowDefinition Height="Auto" /&gt;
              &lt;RowDefinition Height="Auto" /&gt;
          &lt;/Grid.RowDefinitions&gt;
  
          &lt;!-- TEST ITEM --&gt;
          &lt;Border Height="70" BorderBrush="Red" Background="Transparent" BorderThickness="1" HorizontalAlignment="Stretch"&gt;
              &lt;Grid&gt;
                  &lt;Grid.ColumnDefinitions&gt;
                      &lt;ColumnDefinition Width="*" /&gt;
                      &lt;ColumnDefinition Width="Auto" /&gt;
                  &lt;/Grid.ColumnDefinitions&gt;
  
                  &lt;TextBlock Text="Test Item" HorizontalAlignment="Stretch" FontSize="42" /&gt;
                  &lt;Button Content="v" Grid.Column="1" Tap="Button_Tap" Tag="{Binding}"&gt;
  
                  &lt;/Button&gt;
              &lt;/Grid&gt;
          &lt;/Border&gt;
  
          &lt;!-- SUBMENU --&gt;
          &lt;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"&gt;
  
              &lt;i:Interaction.Triggers&gt;
                  &lt;ec:DataTrigger Binding="{Binding SubMenuIsVisible}" Value="True"&gt;
                      &lt;ec:CallMethodAction MethodName="MenuEnabled"
                                              TargetObject="{Binding ElementName=ThisUserControl, Mode=OneWay}" /&gt;
  
                  &lt;/ec:DataTrigger&gt;
  
                  &lt;ec:DataTrigger Binding="{Binding SubMenuIsVisible}" Value="False"&gt;
                      &lt;ec:CallMethodAction MethodName="MenuDisabled" 
                                           TargetObject="{Binding ElementName=ThisUserControl, Mode=OneWay}" /&gt;
                  &lt;/ec:DataTrigger&gt;
              &lt;/i:Interaction.Triggers&gt;
  
              &lt;TextBlock Text="SubMenu" FontSize="42" /&gt;
  
          &lt;/Border&gt;
  
  
      &lt;/Grid&gt;
  &lt;/UserControl&gt;
  </code></pre>
  
  <p>The ItemView codebehind:</p>
  
  <pre><code>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!");
          }
      }
  </code></pre>
  
  <p>And what it looks like:</p>
  
  <p><img src="https://i.stack.imgur.com/UbaaJ.png" alt="list"></p>
  
  <p><strong>/edit 1</strong></p>
  
  <p>I tried turning it into an independent animation using a ScaleTransform, but this won't animate the surrounding ui elements. To fix this you can use a <a href="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" rel="nofollow noreferrer">LayoutTransform</a> instead of the standard RenderTransform. After some tweaking this worked quite nice, but the layouttranform turned it back in a slow depenpendent animation...</p>