【问题标题】:Paged data in a WPF Grid controlWPF Grid 控件中的分页数据
【发布时间】:2013-01-25 11:16:19
【问题描述】:

我有一个以页面形式返回数据的 Rest 服务。我知道得到第一个结果集后有多少页数据。现在我想在 WPF 应用程序中使用这个服务,例如在网格控件(或列表视图)中显示结果。

问题在于整个分页机制对最终用户应该是透明的,因此他们不应该通过在网格中滚动之外的任何方式触发数据获取。这可能吗?您将如何解决这个问题?

【问题讨论】:

    标签: wpf rest data-paging


    【解决方案1】:

    这是您的任务的另一种可能解决方案:http://www.devzest.com/blog/post/wpf-data-virtualization.aspx

    主要思想是创建您自己的 IList 实现,它将封装所有异步页面加载功能。

    作为奖励,该文章包含带有一组附加功能的完整示例代码:

    • 选择、排序和过滤效果很好,就像所有数据都存储在本地一样;
    • 根据需要在单独的线程中加载数据,不会阻塞 UI;
    • 数据加载时的视觉反馈;如果失败,用户可以重试上次失败的尝试。

    【讨论】:

      【解决方案2】:

      将你的网格或列表放入 ScrollViewer,订阅ScrollChanged 事件,然后使用事件 args 属性确定你是否足够接近可滚动区域的末尾,并从你的服务请求下一页,最后添加接收到的数据到列表或网格的末尾。

      简而言之。如果您需要更具体的示例,请告诉我。

      编辑:好的,假设您使用System.Windows.Controls.DataGrid 控件来显示您的数据。我做出这个假设是因为您已经说过您的网格确实具有内置的滚动功能,并且没有其他名称类似于网格的控件具有它。也因为使用 DataGrid 进行数据显示是有意义的。 :)

      您像这样声明您的 DataGrid:

      <DataGrid HorizontalAlignment="Left" Margin="20,10,0,0" 
                VerticalAlignment="Top" Height="301" Width="498" 
                ScrollViewer.ScrollChanged="DataGrid_ScrollChanged_1"
                ItemsSource="{x:Static Fonts.SystemFontFamilies}">            
      </DataGrid>
      

      请注意,我正在使用ScrollViewer.ScrollChanged 路由事件。这是可能的,因为 DataGrid 确实内置了 ScrollViewer。这意味着可以订阅该事件并分析它的参数。

      为了测试目的,我是这样处理这个事件的:

      private void DataGrid_ScrollChanged_1(object sender, ScrollChangedEventArgs e)
          {
              Debug.WriteLine("Extent height: " + e.ExtentHeight + 
                              ", vertical offset: " + e.VerticalOffset + 
                              ", viewport height: " + e.ViewportHeight);
          }
      

      当我的数据网格滚动到顶部时,我看到以下输出:

      Extent height: 267, vertical offset: 0, viewport height: 13
      

      当它滚动到底部时:

      Extent height: 267, vertical offset: 254, viewport height: 13
      

      因此很容易确定何时接近底部并采取相应措施:

      const int threshold = 20;
      if (e.ExtentHeight <= e.VerticalOffset + e.ViewportHeight + threshold) 
      {
          AskForNextPage();
      }
      

      当然,这里有一些细微差别。您需要跟踪您是否已经下载了某些页面,以及您已经加载了多少页面,以避免数据重复和其他不一致。而且,老实说,与我在这里写的相比,这将是最难做的部分。 :)

      【讨论】:

      • 还没有尝试过,但想知道这是否可行,因为网格已经在内部管理数据的滚动。即使使用常规的 WPF 网格控件,也可以欣赏一个更具体的示例(我使用的是我自己处理的第 3 方)。
      • 好的,举个更具体的例子。澄清一下:您使用的是 Grid 还是 DataGrid?
      • 我正在使用 DevExpress 的网格控件,但 DataGrid 上的示例就可以了。
      • hmmm,觉得应该可以,请给我一些时间验证:)
      • 虽然这是一个有效的解决方案,但@Woodman 提供的示例是解决 IMO 问题的更好方法。
      【解决方案3】:

      我认为这个问题很有趣,但答案对于 stackoverflow 窗口来说太长了,所以我构建了一个使用预取集合视图的简单应用程序。

      这有点类似于 Woodman 发布的方法。

      https://github.com/mrange/CodeStack/tree/master/q14793759/AutoFetching

      有趣的代码在类中:PrefetchingCollectionView

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-05-28
        • 2010-10-28
        • 2021-10-16
        • 1970-01-01
        • 2016-10-29
        • 1970-01-01
        相关资源
        最近更新 更多