2011-05-06 21 views
7

Quiero crear un control de usuario basado en ListBox (ListView) con dicha animación: los elementos en el cuadro de lista no se cargan todos a la vez, tienen que cargar paso a paso (elemento por elemento, primero, luego segundo, luego tercero, etc.) con un tiempo de espera entre ellos.Animación de carga del elemento ListBox

¿Cómo puedo hacer eso?

Respuesta

10

Se puede usar un comportamiento Mezcla SDK para esto:.

<ListBox ItemsSource="{Binding Collection, Source={StaticResource SampleData}}"> 
    <i:Interaction.Behaviors> 
     <b:FadeAnimateItemsBehavior Tick="0:0:0.05"> 
      <b:FadeAnimateItemsBehavior.Animation> 
       <DoubleAnimation From="0" To="1" Duration="0:0:0.3"/> 
      </b:FadeAnimateItemsBehavior.Animation> 
     </b:FadeAnimateItemsBehavior> 
    </i:Interaction.Behaviors> 
</ListBox> 
class FadeAnimateItemsBehavior : Behavior<ListBox> 
{ 
    public DoubleAnimation Animation { get; set; } 
    public TimeSpan Tick { get; set; } 

    protected override void OnAttached() 
    { 
     base.OnAttached(); 
     AssociatedObject.Loaded += new System.Windows.RoutedEventHandler(AssociatedObject_Loaded); 
    } 

    void AssociatedObject_Loaded(object sender, System.Windows.RoutedEventArgs e) 
    { 
     IEnumerable<ListBoxItem> items; 
     if (AssociatedObject.ItemsSource == null) 
     { 
      items = AssociatedObject.Items.Cast<ListBoxItem>(); 
     } 
     else 
     { 
      var itemsSource = AssociatedObject.ItemsSource; 
      if (itemsSource is INotifyCollectionChanged) 
      { 
       var collection = itemsSource as INotifyCollectionChanged; 
       collection.CollectionChanged += (s, cce) => 
        { 
         if (cce.Action == NotifyCollectionChangedAction.Add) 
         { 
          var itemContainer = AssociatedObject.ItemContainerGenerator.ContainerFromItem(cce.NewItems[0]) as ListBoxItem; 
          itemContainer.BeginAnimation(ListBoxItem.OpacityProperty, Animation); 
         } 
        }; 

      } 
      ListBoxItem[] itemsSub = new ListBoxItem[AssociatedObject.Items.Count]; 
      for (int i = 0; i < itemsSub.Length; i++) 
      { 
       itemsSub[i] = AssociatedObject.ItemContainerGenerator.ContainerFromIndex(i) as ListBoxItem; 
      } 
      items = itemsSub; 
     } 
     foreach (var item in items) 
     { 
      item.Opacity = 0; 
     } 
     var enumerator = items.GetEnumerator(); 
     if (enumerator.MoveNext()) 
     { 
      DispatcherTimer timer = new DispatcherTimer() { Interval = Tick }; 
      timer.Tick += (s, timerE) => 
      { 
       var item = enumerator.Current; 
       item.BeginAnimation(ListBoxItem.OpacityProperty, Animation); 
       if (!enumerator.MoveNext()) 
       { 
        timer.Stop(); 
       } 
      }; 
      timer.Start(); 
     } 
    } 
} 

Tick especifica el tiempo entre cuando los artículos se empezaron a desvanecerse en Animation es la animación aplicada a la opacidad de la atenuación en, se puede configurar en Xaml para que sea muy costoso (por ejemplo, funciones de aceleración y tiempo de fundido).

Editar:. Agregado nuevo desvanecimiento artículo disponible (sólo funciona si ItemsSource se utiliza e implementa INotifyCollectionChanged)

(fragmentos use el código de este tipo con precaución, si es que este código es principalmente para fines de demostración y dando una idea general de cómo se puede abordar esto. Esto probablemente también podría hacerse usando el nativo de Blend 4 FluidMoveBehaviors si está disponible.)

+0

¡Gracias por la respuesta calificada! Por fin, cómo podría animar elementos sin propiedad Opacidad, pero con propiedad Visibilidad. Lo intenté mucho pero no puedo hacer eso. – JaneKate

+0

Puede animar la visibilidad utilizando un ['ObjectAnimationUsingKeyFrames'] (http://msdn.microsoft.com/en-us/library/system.windows.media.animation.objectanimationusingkeyframes%28v=vs.95%29.aspx), en [esta respuesta] (http://stackoverflow.com/questions/5587374/animating-wpf-datagrid-row-details/5588022#5588022) puede ver un ejemplo. –

+0

¡Gracias! Se intentó encontrar la respuesta porque esa animación (o comportamiento) no tiene un nombre especial (¿acordeón? ¡Puede ser el mejor!). – JaneKate

Cuestiones relacionadas