2012-09-29 13 views
6

A volte trovo che WPF sia imperscrutabile. Dato il seguente XAML, come aggiungerei i trigger per animare (scorrere verso il basso, sfumare) i nuovi elementi aggiunti alla linea temporale ObservableCollection. Ho visto vari esempi per le caselle di elenco ma nulla per il controllo degli elementi.Animate Insertions to ItemsControl

<Grid> 
    <ScrollViewer> 
     <ItemsControl Name="TimelineItem" 
         ItemsSource="{Binding Timeline}" 
         Style="{StaticResource TimelineStyle}" 
         ItemContainerStyle="{StaticResource TweetItemStyle}"> 
      <ItemsControl.ItemTemplate> 
       <DataTemplate> 
        <Grid VerticalAlignment="Top" 
          HorizontalAlignment="Left"> 
         <Grid.ColumnDefinitions> 
          <ColumnDefinition Style="{StaticResource TweetImageColumnStyle}" /> 
          <ColumnDefinition /> 
         </Grid.ColumnDefinitions> 
         <Grid.RowDefinitions> 
          <RowDefinition /> 
          <RowDefinition /> 
          <RowDefinition /> 
          <RowDefinition /> 
         </Grid.RowDefinitions> 
         <Rectangle Grid.Column="0" 
            Style="{StaticResource TweetImageStyle}"> 
          <Rectangle.Fill> 
           <ImageBrush ImageSource="{Binding ProfileImageUrl}" /> 
          </Rectangle.Fill> 
         </Rectangle> 
         <StackPanel Grid.Column="1"> 
          <Grid> 
           <Grid.ColumnDefinitions> 
            <ColumnDefinition Width="*" /> 
            <ColumnDefinition Width="Auto" /> 
           </Grid.ColumnDefinitions> 
           <TextBlock Grid.Column="0" 
              Style="{StaticResource TweetNameStyle}" 
              Text="{Binding Name}" /> 
           <TextBlock Grid.Column="1" 
              Style="{StaticResource TweetTimeStyle}" 
              Text="{Binding TimeAgo}" /> 
          </Grid> 
          <Controls:TextBlockMarkup Grid.Row="1" 
                 Grid.Column="1" 
                 Markup="{Binding MarkupText}" 
                 Style="{StaticResource TweetStyle}" /> 
         </StackPanel> 
         <Separator Grid.Row="2" 
            Grid.ColumnSpan="2" 
            Style="{StaticResource TweetSeparatorTop}" /> 
         <Separator Grid.Row="3" 
            Grid.ColumnSpan="2" 
            Style="{StaticResource TweetSeparatorBottom}" /> 
        </Grid> 
       </DataTemplate> 
      </ItemsControl.ItemTemplate> 
     </ItemsControl> 
    </ScrollViewer> 
</Grid> 

risposta

18

E 'stato un po' che ho animato WPF, ma questo dovrebbe funzionare impostando un DataTrigger nel DataTemplate del ItemsControl per l'evento Loaded.

Un paio di note:

  1. Aggiungere il seguente codice XAML alla DataTemplate del ItemsControl
  2. Nome del <Grid> all'interno del DataTemplate: "MyGrid"
  3. Aggiungi un RenderTransformOriginproperty al MyGrid per impostare il Y origine in alto:
    • <Grid x:Name="MyGrid" RenderTransformOrigin="0.5,0">
  4. essere sicuri di includere il Grid.RenderTransform proprietà associata alla griglia (vedi esempio sotto)

Xaml

<DataTemplate.Resources> 
    <Storyboard x:Key="ItemAnimation" AutoReverse="False"> 
     <DoubleAnimationUsingKeyFrames Storyboard.TargetName="MyGrid" Storyboard.TargetProperty="(UIElement.Opacity)"> 
      <EasingDoubleKeyFrame KeyTime="0" Value="0" /> 
      <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="1" /> 
     </DoubleAnimationUsingKeyFrames> 
     <DoubleAnimationUsingKeyFrames Storyboard.TargetName="MyGrid" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)"> 
      <EasingDoubleKeyFrame KeyTime="0" Value="0" /> 
      <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="1" /> 
     </DoubleAnimationUsingKeyFrames> 
    </Storyboard> 
</DataTemplate.Resources> 

<DataTemplate.Triggers> 
    <EventTrigger RoutedEvent="FrameworkElement.Loaded"> 
     <BeginStoryboard Storyboard="{StaticResource ItemAnimation}" /> 
    </EventTrigger> 
</DataTemplate.Triggers> 

Aggiungere i gruppi RenderTransform alla griglia

<!-- Include in the Grid --> 
<Grid.RenderTransform> 
    <TransformGroup> 
     <ScaleTransform/> 
    </TransformGroup> 
</Grid.RenderTransform> 

Questo dovrebbe aiutarti a personalizzarlo da solo. FWIW: Ho usato Blend per creare l'animazione modificando lo stile dell'oggetto-dell'oggetto Timeline.

Un'ultima nota: l'animazione si verifica quando la finestra carica ItemsControl per la prima volta, per ciascun elemento nella raccolta originale. E si verificherà per un singolo oggetto quando viene aggiunto alla raccolta. Questo comportamento è un po 'fastidioso, quindi è possibile rimuovere il binding esplicito del trigger in xaml e associare il trigger nel code-behind dopo il caricamento di ItemsControl o Window.

EDIT

  1. Ho aggiornato l'esempio in modo che dovrebbe funzionare con il tuo XAML ora.
  2. Aggiunta un'altra animazione per scorrere (sorta di) il nuovo elemento. In realtà, sta crescendo da una dimensione dello 0% al 100%, a partire dalla cima dell'asse Y.
  3. Nota modificata n. 3 da sopra per includere una proprietà RenderTransformOrigin.
  4. Aggiunta la nota n. 4 per includere la proprietà allegata Grid.RenderTransform.
+0

Ottima risposta. L'opacità funziona benissimo ma sto ottenendo un errore con lo slidingown. La proprietà '[Unknown]' non punta a un DependencyObject nel percorso '(0). (1) [3]. (2)'. Ho provato diversi indici di bambini, ma non sono abbastanza sicuro di come interpretare l'errore –

+0

Sembra che avrò bisogno di un gruppo di trasformazione per far funzionare l'animazione dell'altezza.I sorta di preso a lavorare con l'aggiunta di < /TransformGroup>< /Grid.RenderTransform> Pensieri? –

+0

Ho aggiornato l'esempio per correggere l'errore che si stava ricevendo. Stavo usando un xaml leggermente diverso da quello che hai postato a causa di tutte le risorse statiche e il controllo personalizzato. Ho incluso alcune note in fondo alla risposta. HTH di. –