Windows runtime 如何确定GridView中哪些项目在当前滚动窗口中可见?

Windows runtime 如何确定GridView中哪些项目在当前滚动窗口中可见?,windows-runtime,windows-store-apps,Windows Runtime,Windows Store Apps,我的主应用程序页面中有一个GridView,我想对用户当前查看的项目进行一些后台处理(高优先级),然后当然也对其他项目进行处理(低优先级) 我可以访问滚动条和ScrollViewer,但它们都不能告诉我当前滚动窗口中有哪些项目。我可以尝试破解这个问题,但会变得很棘手,因为行/列的数量会根据滚动区域的大小而变化 非常感谢任何帮助 谢谢有两种方法可以做到这一点。首先是获取GridViewItem的AutomationPeer,它实际上有一个直接调用的方法。不过,我在让它实际可用方面遇到了一些问题

我的主应用程序页面中有一个GridView,我想对用户当前查看的项目进行一些后台处理(高优先级),然后当然也对其他项目进行处理(低优先级)

我可以访问滚动条和ScrollViewer,但它们都不能告诉我当前滚动窗口中有哪些项目。我可以尝试破解这个问题,但会变得很棘手,因为行/列的数量会根据滚动区域的大小而变化

非常感谢任何帮助


谢谢

有两种方法可以做到这一点。首先是获取
GridViewItem
AutomationPeer
,它实际上有一个直接调用的方法。不过,我在让它实际可用方面遇到了一些问题。幸运的是,还有第二个答案。这需要做一些数学计算,但这是可行的

  • 使用
    GridView
    ItemContainerGenerator
    获取项目容器,在本例中为
    GridViewItem
  • 获取
    GridView
    ScrollViewer
    。你可以搜索
    FindVisualChild
    方法,有很多
  • 执行MyGridViewItem.TransformToVisual(MyGridViewScrollViewer).TransformPoint(新点(0,0))这将使您获得项目的左上角,相对于
    ScrollViewer
    的整个可滚动面板(称为其
    范围)
    (这在后面很重要)
  • 这将向您返回一个
    对象

    接下来,我们需要找出当前显示在
    ScrollViewer
    中的
    X
    值的范围

    注意:如果您使用的是垂直滚动
    ScrollViewer
    ,请使用
    Height
    s。水平,使用
    宽度
    s。两者都用,两者都用。我将使用水平/宽度来做我的示例

  • 水平偏移量
    。这是当前可视区域的当前“下限”
  • 水平偏移量
    加上
    视口宽度
    。这是当前可视区域的上限
  • 如果
    点.X
    大于下限,小于上限,则该项可见 如果您需要进一步了解整个项目是否可见,请执行以下操作 对于
    Point.X+GridViewItem.Width
    ,这是相同的计算


    希望这对你有帮助,并且编码愉快

    您可以按照Nate的建议使用
    VisualTreeHelper
    扫描可视化树,但通常不建议在运行时使用此方法,尤其是对于紧密循环(例如检查大量
    GridViewItem
    对象)或复杂的可视化树。您可以做一点小小的改进,只计算这些项目的位置一次,然后根据
    ScrollViewer.ViewChanged
    事件和偏移量值进行简化检查,但这似乎有点太复杂了


    如果您的
    GridView
    使用支持虚拟化的
    ItemsPanel
    (例如默认的
    WrapGrid
    )-实际加载到
    GridView
    项目中的大多数项目实际上都是可见的或离屏幕不远,因此,如果您使用
    ItemsSource
    GridView
    绑定到一组视图模型,您可以通过绑定到它们的属性或处理
    itemstemplate
    上的
    Loaded
    Unloaded事件来确定何时访问这些项,并调用视图模型以了解它们何时被访问访问。这样,您就可以在这些项目第一次出现在屏幕上时开始加载它们,并保留逻辑以确定是否应将它们加载到平台中的列表控件虚拟化实现中。

    对于滚动视图区域之外的项目,是否也会启动加载?如果是这样的话,这对我不起作用。我需要区分这两者,以便在用户滚动时动态调整后台加载的优先级。这将适用于屏幕上有点不显示的内容,但不是所有内容。这就是虚拟化的工作原理-它为需要显示在屏幕上的项目创建容器UI元素,如果用户从当前可见区域滚动,则可以快速呈现更多的元素,因此这很可能是您需要的。一个更正#3不正确。它将为您提供项目相对于屏幕视口的位置,因此我只需要确保项目的原点不为负值且不超过视口宽度/高度。我不确定是否遵循步骤1。如果您不知道视图中有哪些项,那么如何从GridViewItem开始?我想更具体地说,GridView.ItemContainerGenerator中的哪个属性/方法为您提供了这个项?在这种情况下,他将不得不迭代他的列表,并每次都这样做。这样做的好处是,在多个列/行的情况下,他将能够始终找到它们,但显然很难用于大型列表。他可以做一些事情来提高大型列表的效率,例如,当他到达“查看中”的项目部分时,以及当他离开列表的该部分时(然后在该点停止迭代)。@NateDiamond是否有代码片段要跟随?很抱歉,我无法理解流程