2011-08-22 156 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這也正是包含什麼,但鏈接的答案都望而卻步。 –