Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Here is a rough implementation based on the same approach as the following link<br> <a href="http://aniscrollviewer.codeplex.com/" rel="noreferrer">http://aniscrollviewer.codeplex.com/</a></p> <p>The <code>VerticalOffset</code> property is read-only so instead you can use an attached property <code>VerticalOffset</code> on the <code>ScrollViewer</code> which in turn does <code>ScrollToVerticalOffset</code>. This attached property can be animated.</p> <p>You can also create an extension method for <code>ItemsControl</code> called <code>AnimateScrollIntoView</code>.</p> <p>Call it like this</p> <pre><code>listBox.AnimateScrollIntoView(yourItem); </code></pre> <p><em>ScrollViewerBehavior</em></p> <pre><code>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); } } } </code></pre> <p><em>ItemsControlExtensions</em></p> <pre><code>public static class ItemsControlExtensions { public static void AnimateScrollIntoView(this ItemsControl itemsControl, object item) { ScrollViewer scrollViewer = VisualTreeHelpers.GetVisualChild&lt;ScrollViewer&gt;(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(); } } </code></pre> <p>And since you also need to get a hold of the <code>ScrollViewer</code> you'll need this</p> <pre><code>public static class VisualTreeHelpers { public static T GetVisualChild&lt;T&gt;(DependencyObject parent) where T : Visual { T child = default(T); int numVisuals = VisualTreeHelper.GetChildrenCount(parent); for (int i = 0; i &lt; numVisuals; i++) { Visual v = (Visual)VisualTreeHelper.GetChild(parent, i); child = v as T; if (child == null) { child = GetVisualChild&lt;T&gt;(v); } if (child != null) { break; } } return child; } } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload