如何在UWP中滚动到元素

14

我如何在ScrollViewer中滚动到特定位置?

 <ScrollViewer x:Name ="MyScrollView" HorizontalScrollBarVisibility="Hidden" Height="500">                      
   <StackPanel x:Name="ContentsPanel">
        <TextBlock x:Name="someTb" Height="50">
        </TextBlock>
        <TextBlock x:Name="otherTb" Height="100">
        </TextBlock>
   </StackPanel>
</ScrollViewer>

我正在尝试在我的滚动视图中滚动到特定元素,但我对UWP不熟悉,不知道如何做。

我想在事件发生时设置第二个文本块中MyScrollView的滚动位置。

3个回答

28

更好的解决方案是使用ChangeView而不是ScrollToVerticalOffset/ScrollToHorizontalOffset,因为后者在Windows 10中已经过时。

MyScrollView.ChangeView(null, abosulatePosition.Y, null, true);

您甚至可以通过将最后一个参数设置为false启用滚动动画。


更新

出于完整性考虑,我已经创建了一个扩展方法。

public static void ScrollToElement(this ScrollViewer scrollViewer, UIElement element, 
    bool isVerticalScrolling = true, bool smoothScrolling = true, float? zoomFactor = null)
{
    var transform = element.TransformToVisual((UIElement)scrollViewer.Content);
    var position = transform.TransformPoint(new Point(0, 0));

    if (isVerticalScrolling)
    {
        scrollViewer.ChangeView(null, position.Y, zoomFactor, !smoothScrolling);
    }
    else
    {
        scrollViewer.ChangeView(position.X, null, zoomFactor, !smoothScrolling);
    }
}

所以在这种情况下,只需要调用

this.MyScrollView.ScrollToElement(otherTb);

1
应该是 MyScrollView.ChangeView(null,abosulatePosition.Y,null,true); - Nejdi Kroi

6
我找到了答案。
    var transform = otherTb.TransformToVisual(ContentsPanel);
    Point absolutePosition = transform.TransformPoint(new Point(0,0));
    MyScrollView.ScrollToVerticalOffset(absolutePosition.Y);

更新

在UWP中,ScrollToVerticalOffset已经过时了,所以需要使用

    MyScrollView.ChangeView(null,absolutePosition.Y,null,true)

应该使用它来代替。请参考https://msdn.microsoft.com/zh-cn/library/windows/apps/dn252763.aspx

-2

这是下面所描述方法的实现视频演示

我曾经使用ScrollViewerOffsetMediator,这是一个扩展方法,依赖于ScrollToVerticalOffset方法来平滑地动画滚动ScrollViewer内容。然而,在Windows 10中,ScrollToVerticalOffset已经被弃用,尽管它在Windows 10的一些早期版本中可以工作,但现在不再支持。

新的ChangeView方法既不能提供平滑的滚动也不能控制滚动视图的内容。因此,这里是我找到的解决方案:

在ScrollViewer中放置一个Grid。使用RenderTransform对网格内容进行动画处理。使用新的ChangeView方法来设置您最终期望的垂直和水平ScrollViewer位置,在设置网格内容动画的变换时。在网格变换中,通过最终期望的ChangeView偏移量来偏移初始值,以便为ChangeView方法造成的立即跳转校正动画开始参考点。

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>

代码:

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

例子:

        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)

在这个例子中,无论ScrollView的初始垂直位置是什么,内容都将平稳地动画到一个固定的垂直位置和缩放比例。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接