Задать вопрос
@llexus

Анимация скроллинга LongListSelector (или ListBox)?

Привет. Задачу поставил себе следующую:

Есть LongListSelector. Как только в него загрузились данные, из кода нужно проскроллить до определенного элемента.

Я использовал ScrollTo. Функция работает, но мне показалось этого мало. Решил погуглить как можно это дело красиво анимировать. Есть некая депрекейтнутая функция AnimateTo. Попробовал - эффект как и ScrollTo, никаких анимаций.

Дальшейшее гугление подало идею добавть свою DependencyProperty на вертикальный офсет скрола:
public partial class LongListSelector : Control
    {
        public static childItem FindVisualChild<childItem>(DependencyObject obj) where childItem : DependencyObject
        {
            for (int i = 0; i <= VisualTreeHelper.GetChildrenCount(obj) - 1; i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(obj, i);

                if (child != null && child is childItem)
                    return (childItem)child;
                else
                {
                    childItem childOfChild = FindVisualChild<childItem>(child);

                    if (childOfChild != null)
                        return childOfChild;
                }
            }

            return null;
        }

        public static readonly DependencyProperty VerticalOffsetProperty = DependencyProperty.Register("VerticalOffset",
           typeof(double), typeof(LongListSelector), new PropertyMetadata(VerticalOffsetPropertyChanged));
        public double VerticalOffset
        {
            get { return (double)this.GetValue(VerticalOffsetProperty); }
            set { this.SetValue(VerticalOffsetProperty, value); }
        }
        private static void VerticalOffsetPropertyChanged(object sender, DependencyPropertyChangedEventArgs args)
        {
            LongListSelector cThis = sender as LongListSelector;
            ScrollViewer LScrollViewer = FindVisualChild<ScrollViewer>(cThis);
            LScrollViewer.ScrollToVerticalOffset((double)args.NewValue);
        }
        public static readonly DependencyProperty ContentAreaProperty = DependencyProperty.Register("ContentArea", typeof(object), typeof(LongListSelector), null);
        public object ContentArea
        {
            get { return (object)GetValue(ContentAreaProperty); }
            set { SetValue(ContentAreaProperty, value); }
        }
...

Сделано. Пробую проскролить куда-нибудь...
DoubleAnimation verticalAnimation = new DoubleAnimation();
            verticalAnimation.From = 0;
            verticalAnimation.To = 25;
            verticalAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(5000));
            CubicEase ea = new CubicEase();
            ea.EasingMode = EasingMode.EaseInOut;
            verticalAnimation.EasingFunction = ea;
            var sb = new Storyboard();
            sb.Children.Add(verticalAnimation);
            Storyboard.SetTarget(verticalAnimation, buddies);
            Storyboard.SetTargetProperty(verticalAnimation, new PropertyPath(LongListSelector.VerticalOffsetProperty));
            sb.Begin();

Все классно, плавно скроллит. А вот теперь собвстевнно вопрос:

Как правильно определить verticalAnimation.To ? К прмеру, для огромного списка интервал скроллирования (ScrollViewer.ScrollableHeight) получился от 0 до 119. Почему 119? В чем это измеряется? По факту весь список занимает экранов дцать, т.е много тысяч пикселей. И как мне вычислить это значение, если я, напрмер, хочу проскролить к N элементу в списке?
  • Вопрос задан
  • 2347 просмотров
Подписаться 2 Оценить Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы