2011-08-22 7 views
5

¿Cómo puedo animar el desplazamiento para ListBox? Sé que puedo usar scrollIntoView, pero ¿cómo puedo animarlo? Quiero presionar las teclas de flecha para pasar de un listBoxItem a otro.Animación de desplazamiento

Respuesta

7

Aquí es una aplicación aproximado basado en los mismos principios que el siguiente enlace
http://aniscrollviewer.codeplex.com/

lo que en lugar se puede utilizar una propiedad adjunta VerticalOffset en el ScrollViewer que a su vez hace ScrollToVerticalOffset La propiedad VerticalOffset es de sólo lectura. Esta propiedad adjunta puede ser animada.

También puede crear un método de extensión para ItemsControl llamado AnimateScrollIntoView.

llamarlo como esto

listBox.AnimateScrollIntoView(yourItem); 

ScrollViewerBehavior

public class ScrollViewerBehavior 
{ 
    public static DependencyProperty VerticalOffsetProperty = 
     DependencyProperty.RegisterAttached("VerticalOffset", 
              typeof(double), 
              typeof(ScrollViewerBehavior), 
              new UIPropertyMetadata(0.0, OnVerticalOffsetChanged)); 

    public static void SetVerticalOffset(FrameworkElement target, double value) 
    { 
     target.SetValue(VerticalOffsetProperty, value); 
    } 
    public static double GetVerticalOffset(FrameworkElement target) 
    { 
     return (double)target.GetValue(VerticalOffsetProperty); 
    } 
    private static void OnVerticalOffsetChanged(DependencyObject target, DependencyPropertyChangedEventArgs e) 
    { 
     ScrollViewer scrollViewer = target as ScrollViewer; 
     if (scrollViewer != null) 
     { 
      scrollViewer.ScrollToVerticalOffset((double)e.NewValue); 
     } 
    } 
} 

ItemsControlExtensions

public static class ItemsControlExtensions 
{ 
    public static void AnimateScrollIntoView(this ItemsControl itemsControl, object item) 
    { 
     ScrollViewer scrollViewer = VisualTreeHelpers.GetVisualChild<ScrollViewer>(itemsControl); 

     UIElement container = itemsControl.ItemContainerGenerator.ContainerFromItem(item) as UIElement; 
     int index = itemsControl.ItemContainerGenerator.IndexFromContainer(container); 
     double toValue = scrollViewer.ScrollableHeight * ((double)index/itemsControl.Items.Count); 
     Point relativePoint = container.TranslatePoint(new Point(0.0, 0.0), Window.GetWindow(container)); 

     DoubleAnimation verticalAnimation = new DoubleAnimation(); 
     verticalAnimation.From = scrollViewer.VerticalOffset; 
     verticalAnimation.To = toValue; 
     verticalAnimation.DecelerationRatio = .2; 
     verticalAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(1000)); 
     Storyboard storyboard = new Storyboard(); 
     storyboard.Children.Add(verticalAnimation); 
     Storyboard.SetTarget(verticalAnimation, scrollViewer); 
     Storyboard.SetTargetProperty(verticalAnimation, new PropertyPath(ScrollViewerBehavior.VerticalOffsetProperty)); 
     storyboard.Begin(); 
    } 
} 

y dado que también es necesario para obtener una bodega del ScrollViewer que necesita este

public static class VisualTreeHelpers 
{ 
    public static T GetVisualChild<T>(DependencyObject parent) where T : Visual 
    { 
     T child = default(T); 

     int numVisuals = VisualTreeHelper.GetChildrenCount(parent); 
     for (int i = 0; i < numVisuals; i++) 
     { 
      Visual v = (Visual)VisualTreeHelper.GetChild(parent, i); 
      child = v as T; 
      if (child == null) 
      { 
       child = GetVisualChild<T>(v); 
      } 
      if (child != null) 
      { 
       break; 
      } 
     } 
     return child; 
    } 
} 
+0

¿Cuál sería la animación para valorar si quiero desplazarme horizontalmente? – Cobold

+2

Puede haber un error en el código: 'scrollViewer.ScrollableHeight * ((double) index/itemsControl.Items.Count); ' debe ser ' scrollViewer.ScrollableHeight * ((double) index/(itemsControl.Items.Count -1)); ' por ejemplo, si la lista contiene 12 elementos y quiero para desplazarse hasta la última (índice 11), el resultado tiene que convertirse en ' scrollViewer.ScrollableHeight * 1' También, tenga cuidado con la división por cero:) – sim1

+0

@ sim1: No he mirado este durante mucho tiempo, así que estoy seguro de que tienes razón. Gracias por la actualización :) –

0

Eche un vistazo a este article, explica cómo el desplazamiento animado y agrega gestos táctiles. Descargue la fuente en la parte inferior de la página y mire la solución WpfScrollContent. Extendería el ListBox de WPF y le agregaría la animación de desplazamiento de esa manera usted puede reutilizar el control.

+1

enlace roto .... Hace – patrickbadley

+0

publicado más de 2 años ... – evanb

+1

@evanb que es exactamente por qué no se animan respuestas que contienen nada más que enlaces. –

Cuestiones relacionadas