Привет. Задачу поставил себе следующую:
Есть 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 элементу в списке?