Here is a Video demo of the method described below, implemented.
I used to use the ScrollViewerOffsetMediator, an extension method which relied upon the ScrollToVerticalOffset method to smoothly animate scrolling of the ScrollViewer contents. However, ScrollToVerticalOffset has been deprecated in Windows 10, and although it worked in some earlier releases of Windows 10, it no longer does.
The new ChangeView method does not provide either smooth nor controllable animation of the ScrollViewer contents. So here is the solution that I've found:
Place a Grid within the ScrollViewer. Animate the contents of the grid using a RenderTransform. Use the new ChangeView method to set your final desired vertical and horizontal ScrollViewer positions at the time you set up your animation of the grid contents via the transformation. And in your grid transformation, offset the initial values by the final desired ChangeView offset, so that the animation start reference is corrected for the immediate jump that will be caused by the ChangeView method.
XAML:
<ScrollViewer x:Name="MyScrollView">
<Grid Name="MyGrid">
<Grid.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1"/>
<TranslateTransform X="0" Y="0"/>
</TransformGroup>
</Grid.RenderTransform>
<!-- Original ScrollViewer Contents Here... -->
</Grid>
</ScrollViewer>
Code:
Public Sub AnimateProperty(Obj As DependencyObject, PropPath As String, StartValue As Double, EndValue As Double, Optional PeriodMS As Integer = 350)
Dim Storya As New Storyboard
Dim DA1 As New DoubleAnimationUsingKeyFrames With {.BeginTime = New TimeSpan(0, 0, 0)}
Storyboard.SetTarget(DA1, Obj)
Storyboard.SetTargetProperty(DA1, PropPath)
Dim ddkf1 As New DiscreteDoubleKeyFrame With {.KeyTime = New TimeSpan(0, 0, 0), .Value = StartValue}
Dim edkf1 As New EasingDoubleKeyFrame With {.Value = EndValue, .KeyTime = New TimeSpan(0, 0, 0, 0, PeriodMS)}
Dim pe1 As New PowerEase With {.EasingMode = EasingMode.EaseIn}
edkf1.EasingFunction = pe1
DA1.KeyFrames.Add(ddkf1)
DA1.KeyFrames.Add(edkf1)
Storya.Children.Add(DA1)
Storya.Begin()
End Sub
Example:
AnimateProperty(MyGrid, "(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)", 1, 1.4, 350)
AnimateProperty(MyGrid, "(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)", 1, 1.4, 350)
AnimateProperty(MyGrid, "(UIElement.RenderTransform).(TransformGroup.Children)[1].(TranslateTransform.Y)", -MyScrollView.VerticalOffset, -120, 350)
MyScrollView.ChangeView(Nothing, 0, Nothing, True)
In this example, no matter what the initial vertical position is of the ScrollView, the contents will be smoothly animated to a fixed vertical position and zoom.