【问题标题】:UWP GridView - How to maintain visible items upon resizing (Column count changes)UWP GridView - 如何在调整大小时保持可见项目(列数更改)
【发布时间】:2018-10-17 04:46:10
【问题描述】:

我有一个GridView,用于显示 数千张 图像/缩略图(使用数据绑定)。我使用 ImplicitAnimations 来添加过渡,这样当控件调整大小并且列数发生变化时 - 每个项目都会在调整大小后顺利进入新位置。

问题

当用户位于GridView 的顶部时,这一切都可以正常工作,但用户滚动得越远就会出现问题。滚动得越远,当列数发生变化时,移动的项目就越多。添加/删除更多行,但滚动条保持在相同的位置/偏移量,这会导致以前可见的项目远离视图 - 并且用户会迷路。

到目前为止我尝试了什么......

我尝试通过跟踪每个滚动更改事件上的第一个可见项目,然后在 SizeChanged 事件上滚动到它来解决此问题。然而,这个解决方案的问题在于它确实粗糙。动画不再引人注意,整个体验变得迟钝。

有没有更好的办法解决这个问题?

问题说明

视频示例

我还制作了一个视频来更好地说明这个问题。

(图片已经模糊,因为有些是 NSFW)

Video Link

我正在寻找的是一种让滚动条在调整大小时调整其位置并保持在用户正在查看的相同项目上的方法 - 而不会弄乱动画。

编辑

显然,这无法以任何其他方式解决,只能手动滚动到我希望在调整大小时可见的项目,我已经尝试过这样做并且动画再次变得非常粗糙,因为 ScrollToItem 发生在之后正在触发动画。

所以我现在的问题是 - 在动画被触发之前,我可以滚动到重新排序/调整大小的项目吗?这样我想我可以保持平滑。但是,使用 resize 事件对此不起作用。

编辑 2 - 代码示例

<GridView x:Name="mylist" animations:ReorderGridAnimation.Duration="600" ItemsSource="{Binding Source={StaticResource viewSource}}">
<GridView.ItemsPanel>
    <ItemsPanelTemplate>
        <ItemsWrapGrid Orientation="Horizontal" HorizontalAlignment="Center" Loaded="ItemsWrapGrid_Loaded"/>
    </ItemsPanelTemplate>
</GridView.ItemsPanel>
<GridView.ItemTemplate>
    <DataTemplate>
        <Grid Width="300" Height="300" Background="Gainsboro">
            <Image Source="{Binding ThumbnailImage}" />
        </Grid>
    </DataTemplate>
</GridView.ItemTemplate>
</GridView>

GridView ItemSource 绑定到下面的 CollectionView

<UserControl.Resources>
    <controls:AdvancedCollectionView x:Key="viewSource" Source="{x:Bind Collection}" />
</UserControl.Resources>

我切换到动画社区工具包和 AdvancedCollectionView。使用自定义面板有两个原因 - 获取面板并向其应用隐式动画 - 并在 Horizo​​ntalAlignment 为 Center 时将滚动条保持在最右侧。

CollectionView 绑定到 ObservableCollection。

要重现该问题 - 只需将大量项目添加到 ItemSource 并尝试以不同的滚动偏移量调整 GridView 的大小(查看视频示例) .

【问题讨论】:

  • 您可以尝试使用 UWP 社区工具包ReorderGridAnimationdocs.microsoft.com/en-us/windows/uwpcommunitytoolkit/animations/…。它很容易集成,但是如果您需要某种自定义动画来重新排序,那将无济于事..
  • 我检查了它,它的工作方式与我现有的动画相同 - 所以它不能解决问题。当我尝试进一步向下调整网格视图的大小时,整个事情开始滞后,并且项目开始疯狂地飞来飞去。
  • 你可以分享一个 gif 来展示这种行为吗?我在我的应用程序中使用重新排序动画,它具有增量加载(和大量项目),但即使在 W10 移动设备上它仍然不会滞后..
  • 我添加了一个视频链接。
  • 好的,所以我可以重现该问题.. 似乎当加载了很多项目时,动画有点消失了..(您应该在 Msft 论坛或 uwp 工具包 GitHub 存储库中报告此问题)..至于显示的项目正在发生变化,因为滚动查看器的滚动偏移量保持不变,而项目分散或堆叠在一起..所以你需要跟踪最近加载的项目和滚动查看.

标签: c# gridview uwp uwp-xaml


【解决方案1】:

对于您的这个问题,可能是ListView and GridView UI virtualization引起的,您可以尝试使用VariableSizedWrapGrid作为GridView的ItemsPanel,

<GridView>
    <GridView.ItemsPanel>
        <ItemsPanelTemplate>
            <VariableSizedWrapGrid/>
        </ItemsPanelTemplate>
    </GridView.ItemsPanel>
</GridView>

但是如果没有虚拟化,它将花费大量设备内存和性能。因此,您还应该考虑一次显示多张图片。

至于显示用户正在查看的项目,由于屏幕中显示的项目很多,GridView 不知道跟踪女巫。所以也如@Pratyay 的建议,您需要跟踪项目然后让 ScrollView 女巫在 GridView 中滚动到该项目。

【讨论】:

  • VariableSizedWrapGrid 不是一个选项,因为我肯定需要为此进行虚拟化。我已经提到尝试跟踪最后一个可见项目,然后在调整大小时滚动到它 - 但是这样做时动画会变得混乱。到目前为止,我唯一的想法,看看它如何无法以任何其他方式解决 - 在动画被触发之前滚动到新项目,但调整大小事件发生在动画之后。我该怎么办?
  • 您能否提供一个简单的重现示例让我查看您的代码?
  • 添加了代码示例。
  • 如果你在屏幕上显示了很多图像并进一步滚动到顶部,当你调整窗口大小时,有这么多项目应该在特定时间重新排列它们的位置,它会让你看到动画强硬。但在我的测试中,动画在最新的OS版本17134上看起来更好,你可以试一试。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-24
  • 2011-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多