2

У меня есть LongListSelector, который заполнен некоторыми элементами. Каждый элемент имеет подменю, которое может быть видимым или свернутым с использованием скользящей анимации. Проблема в том, что анимация очень медленная, в зависимости от того, какой элемент вы используете в списке. В начале и в конце он медленный, посередине он гладкий. Я подозреваю, что каждый кадр анимации делает недействительным longlistselector, что означает, что все визуальное дерево должно обновлять его макет.Медленная анимация раскадровки внутри LongListSelector

Я использую datatrigger, чтобы начать анимацию. Из-за этого я вижу, что триггеры на множестве других предметов также увольняются, что указывает на то, что они перерисовываются. Это также показывает, что когда вы нажимаете в середине списка, намного меньше других элементов также срабатывает. странно ...

Я принимал TestProject на GitHub: https://github.com/jessetabak/wpanimationproblem

LongListSelector:

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

ItemView:

<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!"); 
     } 
    } 

И как это выглядит:

list

/редактировать 1

Я попытался превратить его в независимой анимации с использованием ScaleTransform, но это не будет анимировать окружающие элементы пользовательского интерфейса. Чтобы исправить это, вы можете использовать LayoutTransform вместо стандартного RenderTransform. После некоторой настройки это сработало довольно хорошо, но layouttranform вернул его обратно в медленной зависимой анимации ...

+0

У вас есть решение проблемы? Как описано в pantaloons, я попытался использовать независимые анимации, используя transform -> scale, но тогда элементы ниже меняют свое положение, а анимированный элемент перекрывает их. – sust86

+0

@ sust86 Я обновил свой пост – Jesse

+0

«но layouttranform вернул его обратно в медленной зависимой анимации ...» Итак, это не решение нашей главной проблемы? :( – sust86

ответ

1

Вы правы, что изменение высоты UserControl приводит к недействительности значительной части визуального дерева, но это необходимо , и по дизайну. Проблема в том, что вы сначала изменяете высоту элементов управления в раскадровке, которая не является независимой анимацией и не может работать на компоновщике.

Прочитайте http://msdn.microsoft.com/en-us/library/windows/apps/jj819807.aspx#dependent, хотя это приложение для приложений Windows (а также флаг EnableDependentAnimations в SL), идеи остаются прежними. Вам нужно выяснить способ расширения элементов, используя независимые анимации, возможно, используя ScaleTransform.

+0

Спасибо! Выглядит очень многообещающе. Я вернусь, когда буду отработал. – Jesse

Смежные вопросы