2011-08-22 162 views
5

如何为ListBox的滚动设置动画效果?我知道我可以使用scrollIntoView,但我怎么能动画它?我想按箭头键从一个listBoxItem移动到另一个。滚动动画

回答

7

这是基于同样的方法,因为下面的链接
http://aniscrollviewer.codeplex.com/

VerticalOffset属性为只读,因此,你可以在ScrollViewer这又确实ScrollToVerticalOffset使用附加属性VerticalOffset一个粗略的实现。这个附属的属性可以是动画的。

您还可以为ItemsControl创建名为AnimateScrollIntoView的扩展方法。

这样称呼它

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

而且因为你还需要得到0123的举行你需要这个

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

如果我想水平滚动,animation.to的值是多少? – Cobold

+2

代码中可能有错误: 'scrollViewer.ScrollableHeight *((double)index/itemsControl.Items.Count); ' 应该是 'scrollViewer.ScrollableHeight *((double)index /(itemsControl.Items.Count -1)); ' 例如,如果列表中包含12个元素,我想滚动到最后一个(指数11),其结果有可能成为 'scrollViewer.ScrollableHeight * 1' 也由零提防师: ) – sim1

+0

@ sim1:很久没有看过这个,所以我相信你是对的。感谢您的更新:) –

0

看看这article,它解释了如何动画滚动和添加触摸手势。在页面底部下载源代码并查看WpfScrollContent解决方案。我将扩展WPF列表框并将滚动动画添加到它,以便您可以重新使用该控件。

+1

断开的链接.... – patrickbadley

+0

张贴2年多前... – evanb

+1

@evanb这也正是包含什么,但链接的答案都望而却步。 –