2011-08-22 13 views
5

Come è possibile animare lo scorrimento di ListBox? So che posso usare scrollIntoView ma come posso animarlo? Voglio premere i tasti freccia per spostarmi da un oggetto ListBox a un altro.Animazione di scorrimento

risposta

7

Ecco un'implementazione approssimativa basata sullo stesso approccio come il seguente link
http://aniscrollviewer.codeplex.com/

La proprietà VerticalOffset è in sola lettura così invece è possibile utilizzare una proprietà associata VerticalOffset sul ScrollViewer che a sua volta fa ScrollToVerticalOffset. Questa proprietà associata può essere animata.

È inoltre possibile creare un metodo di estensione per ItemsControl chiamato AnimateScrollIntoView.

chiamare in questo modo

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(); 
    } 
} 

e dal momento che è anche necessario per ottenere una sospensione del ScrollViewer avrete bisogno di questo

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

Quale sarebbe il valore di animazione.to se voglio scorrere orizzontalmente? – Cobold

+2

Potrebbe esserci un errore nel codice: 'scrollViewer.ScrollableHeight * ((double) index/itemsControl.Items.Count); ' deve essere ' scrollViewer.ScrollableHeight * ((double) index/(itemsControl.Items.Count -1)); ' per esempio, se l'elenco contiene 12 elementi e voglio scorrere fino all'ultimo (indice 11), il risultato è di diventare ' scrollViewer.ScrollableHeight * 1' anche, attenzione divisione per zero:) – sim1

+0

@ sim1: Non ho guardato a questo per molto tempo quindi sono sicuro che hai ragione. Grazie per l'aggiornamento :) –

0

Dai un'occhiata a questo article, spiega come lo scorrimento è animato e aggiungi gesti tattili. Scarica la fonte nella parte inferiore della pagina e guarda la soluzione WpfScrollContent. Estenderei il ListBox WPF e aggiungerò l'animazione a scorrimento in questo modo per riutilizzare il controllo.

+1

link interrotto .... – patrickbadley

+0

pubblicato oltre 2 anni fa ... – evanb

+1

@evanb che è esattamente il motivo per le risposte che contengono nulla, ma i collegamenti sono scoraggiati. –

Problemi correlati