当向下滚动时,Groove将标题向上移动到可视区域之外,就像常规ListView标题一样。向后滚动时,无论当前的垂直滚动偏移如何,它都会立即将标题向下移回可视区域。标题似乎是ListView内容的一部分,因为滚动条包含标题。
如何在Windows 10 UWP应用程序中实现?
答案 0 :(得分:1)
您可以使用ListView's
内部ScrollViewer's
ViewChanged
事件来执行此操作。
首先,你必须获得内部ScrollViewer
。这是最简单的版本,但您可能希望使用众多VisualTreeHelper Extensions中的一个来更安全,更轻松地使用它:
private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
var border = VisualTreeHelper.GetChild(MyListView, 0);
var scrollviewer = VisualTreeHelper.GetChild(border, 0) as ScrollViewer;
scrollviewer.ViewChanged += Scrollviewer_ViewChanged;
}
在EventHandler中,您可以根据滚动方向更改标题的可见性。
private void Scrollviewer_ViewChanged(object sender, ScrollViewerViewChangedEventArgs e)
{
var sv = sender as ScrollViewer;
if (sv.VerticalOffset > _lastVerticalOffset)
{
MyHeader.Visibility = Visibility.Collapsed;
}
else
{
MyHeader.Visibility = Visibility.Visible;
}
}
这是基本的想法。您可能无法添加一些流畅的动画,而不仅仅是更改可见性。
答案 1 :(得分:0)
看了一下实验后,我现在可以回答我自己的问题了。
可以使用基于composition animation的表达式来调整与滚动相关的标题的Y偏移量。这个想法是基于这个answer。我在GitHub上准备了一个完整的工作示例。
动画是在ListView的SizeChanged事件中准备的:
ScrollViewer scrollViewer = null;
private double previousVerticalScrollOffset = 0.0;
private CompositionPropertySet scrollProperties;
private CompositionPropertySet animationProperties;
SizeChanged += (sender, args) =>
{
if (scrollProperties == null)
scrollProperties = ElementCompositionPreview.GetScrollViewerManipulationPropertySet(scrollViewer);
var compositor = scrollProperties.Compositor;
if (animationProperties == null)
{
animationProperties = compositor.CreatePropertySet();
animationProperties.InsertScalar("OffsetY", 0.0f);
}
var expressionAnimation = compositor.CreateExpressionAnimation("animationProperties.OffsetY - ScrollingProperties.Translation.Y");
expressionAnimation.SetReferenceParameter("ScrollingProperties", scrollProperties);
expressionAnimation.SetReferenceParameter("animationProperties", animationProperties);
var headerVisual = ElementCompositionPreview.GetElementVisual((UIElement)Header);
headerVisual.StartAnimation("Offset.Y", expressionAnimation);
};
animationProperties中的OffsetY变量将驱动标题的OffsetY属性的动画。 OffsetY变量在ScrollViewer的ViewChanged事件中更新:
scrollViewer.ViewChanged += (sender, args) =>
{
float oldOffsetY = 0.0f;
animationProperties.TryGetScalar("OffsetY", out oldOffsetY);
var delta = scrollViewer.VerticalOffset - previousVerticalScrollOffset;
previousVerticalScrollOffset = scrollViewer.VerticalOffset;
var newOffsetY = oldOffsetY - (float)delta;
// Keep values within negativ header size and 0
FrameworkElement header = (FrameworkElement)Header;
newOffsetY = Math.Max((float)-header.ActualHeight, newOffsetY);
newOffsetY = Math.Min(0, newOffsetY);
if (oldOffsetY != newOffsetY)
animationProperties.InsertScalar("OffsetY", newOffsetY);
};
虽然这样可以正确设置动画,但标题不会堆叠在ListView项目的顶部。因此,拼图的最后一部分是减少ListView的ItemsPanelTemplate的ZIndex:
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsStackPanel Canvas.ZIndex="-1" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
结果就是这样: