如何滚动到 UWP 中的元素
How to scroll to element in UWP
如何滚动到滚动查看器中的特定位置?
<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 的滚动位置。
我找到了答案
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/en-us/library/windows/apps/dn252763.aspx
更好的解决方案是使用 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);
这里是Video demo下面描述的方法,已实现。
我曾经使用 ScrollViewerOffsetMediator,这是一种扩展方法,它依赖于 ScrollToVerticalOffset 方法来平滑滚动 ScrollViewer 内容的动画。但是,ScrollToVerticalOffset 在 Windows 10 中已被弃用,尽管它在 Windows 10 的一些早期版本中有效,但它不再有效。
新的 ChangeView 方法不提供 ScrollViewer 内容的平滑或可控动画。这是我找到的解决方案:
在 ScrollViewer 中放置一个网格。使用 RenderTransform 为网格的内容设置动画。在通过转换设置网格内容动画时,使用新的 ChangeView 方法设置 final 所需的垂直和水平 ScrollViewer 位置。在您的网格转换中,将 initial 值偏移 final 所需的 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 的初始垂直位置是什么,内容都将平滑地动画到固定的垂直位置并缩放。
如何滚动到滚动查看器中的特定位置?
<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 的滚动位置。
我找到了答案
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/en-us/library/windows/apps/dn252763.aspx
更好的解决方案是使用 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);
这里是Video demo下面描述的方法,已实现。
我曾经使用 ScrollViewerOffsetMediator,这是一种扩展方法,它依赖于 ScrollToVerticalOffset 方法来平滑滚动 ScrollViewer 内容的动画。但是,ScrollToVerticalOffset 在 Windows 10 中已被弃用,尽管它在 Windows 10 的一些早期版本中有效,但它不再有效。
新的 ChangeView 方法不提供 ScrollViewer 内容的平滑或可控动画。这是我找到的解决方案:
在 ScrollViewer 中放置一个网格。使用 RenderTransform 为网格的内容设置动画。在通过转换设置网格内容动画时,使用新的 ChangeView 方法设置 final 所需的垂直和水平 ScrollViewer 位置。在您的网格转换中,将 initial 值偏移 final 所需的 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 的初始垂直位置是什么,内容都将平滑地动画到固定的垂直位置并缩放。