有没有一种方法能够在Windows Phone 8.1 Runtime中平滑地动画化ScrollViewer
的垂直偏移量?
我尝试过使用ScrollViewer.ChangeView()
方法,但无论我将disableAnimation
参数设置为true还是false,垂直偏移的变化都没有被动画化。
例如:myScrollViewer.ChangeView(null, myScrollViewer.VerticalOffset + p, null, false);
偏移量会改变,但没有动画效果。
我还尝试使用了一个垂直偏移调解器:
/// <summary>
/// Mediator that forwards Offset property changes on to a ScrollViewer
/// instance to enable the animation of Horizontal/VerticalOffset.
/// </summary>
public sealed class ScrollViewerOffsetMediator : FrameworkElement
{
/// <summary>
/// ScrollViewer instance to forward Offset changes on to.
/// </summary>
public ScrollViewer ScrollViewer
{
get { return (ScrollViewer)GetValue(ScrollViewerProperty); }
set { SetValue(ScrollViewerProperty, value); }
}
public static readonly DependencyProperty ScrollViewerProperty =
DependencyProperty.Register("ScrollViewer",
typeof(ScrollViewer),
typeof(ScrollViewerOffsetMediator),
new PropertyMetadata(null, OnScrollViewerChanged));
private static void OnScrollViewerChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
var mediator = (ScrollViewerOffsetMediator)o;
var scrollViewer = (ScrollViewer)(e.NewValue);
if (null != scrollViewer)
{
scrollViewer.ScrollToVerticalOffset(mediator.VerticalOffset);
}
}
/// <summary>
/// VerticalOffset property to forward to the ScrollViewer.
/// </summary>
public double VerticalOffset
{
get { return (double)GetValue(VerticalOffsetProperty); }
set { SetValue(VerticalOffsetProperty, value); }
}
public static readonly DependencyProperty VerticalOffsetProperty =
DependencyProperty.Register("VerticalOffset",
typeof(double),
typeof(ScrollViewerOffsetMediator),
new PropertyMetadata(0.0, OnVerticalOffsetChanged));
public static void OnVerticalOffsetChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
var mediator = (ScrollViewerOffsetMediator)o;
if (null != mediator.ScrollViewer)
{
mediator.ScrollViewer.ScrollToVerticalOffset((double)(e.NewValue));
}
}
/// <summary>
/// Multiplier for ScrollableHeight property to forward to the ScrollViewer.
/// </summary>
/// <remarks>
/// 0.0 means "scrolled to top"; 1.0 means "scrolled to bottom".
/// </remarks>
public double ScrollableHeightMultiplier
{
get { return (double)GetValue(ScrollableHeightMultiplierProperty); }
set { SetValue(ScrollableHeightMultiplierProperty, value); }
}
public static readonly DependencyProperty ScrollableHeightMultiplierProperty =
DependencyProperty.Register("ScrollableHeightMultiplier",
typeof(double),
typeof(ScrollViewerOffsetMediator),
new PropertyMetadata(0.0, OnScrollableHeightMultiplierChanged));
public static void OnScrollableHeightMultiplierChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
var mediator = (ScrollViewerOffsetMediator)o;
var scrollViewer = mediator.ScrollViewer;
if (null != scrollViewer)
{
scrollViewer.ScrollToVerticalOffset((double)(e.NewValue) * scrollViewer.ScrollableHeight);
}
}
}
我可以使用DoubleAnimation
动画来操控VerticalOffset
属性:
Storyboard sb = new Storyboard();
DoubleAnimation da = new DoubleAnimation();
da.EnableDependentAnimation = true;
da.From = Mediator.ScrollViewer.VerticalOffset;
da.To = da.From + p;
da.Duration = new Duration(TimeSpan.FromMilliseconds(300));
da.EasingFunction = new ExponentialEase() { EasingMode = EasingMode.EaseOut };
Storyboard.SetTarget(da, Mediator);
Storyboard.SetTargetProperty(da, "(Mediator.VerticalOffset)");
sb.Children.Add(da);
sb.Begin();
中介者在 XAML 中声明。 但是在我的设备上(Lumia 930),这个动画不够流畅。
WinRTXamlToolkit
的ScrollToVerticalOffsetWithAnimation
扩展功能。你可以手动实现它,或通过Nuget添加该库。 - Nate DiamondChangeView
不执行动画吗?无论虚拟化是否开启,它都应该执行动画。 - Justin XLListView
的ScrollViewer
,但它从未进行过动画。也许是因为我的数据模板太复杂了,但我怀疑这一点,因为滚动非常流畅,只是编程滚动不行。当我使用ChangeView
时,它只是改变垂直偏移而没有动画效果。 - Kristian Vukusic