WPF 数据网格延迟加载

发布于 2024-10-31 20:54:13 字数 1432 浏览 4 评论 0原文

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

拥醉 2024-11-07 20:54:13

加载数据:200k 行是大量数据,没有人(用户)愿意在一个地方看到。它肯定会降低你的 UI 用户体验。因此,最好的选择是过滤数据以减少数据量(例如,不显示已关闭的订单,仅显示未关闭的订单)。如果你不能这样做,你应该使用虚拟化。我没有看到任何使用分页来显示数据的应用程序(当然除了网络)。大多数时候这并不是一个好的方法。但如果您谈论的是一种类似于搜索引擎结果的数据,则必须使用它。但请记住,大多数用户在搜索引擎结果中不会超过第 10 页。

过滤:对于如此大量的数据(这里是SQL Server),我建议在服务器端执行此操作,或者正如我所说,首先过滤整个200k以减少服务器端的数据量,然后再过滤它(对于用户)为了在客户端找到某些东西。您可能还会发现以下链接很有帮助:

  1. http://www.codeproject.com/KB/ WPF/DataGridFilterLibrary.aspx

排序: 我再次建议服务器客户端解决方案,但您可能还会发现以下链接很有帮助:

  1. http://blogs.msdn.com/b/jgoldb/archive/2008/ 08/26/improving-microsoft-datagrid-ctp-sorting-performance.aspx
  2. http://blogs.msdn.com/b/jgoldb/archive/2008/08/28/improving-microsoft-datagrid- ctp-sorting-performance-part-2.aspx
  3. http://blogs.msdn.com/b/jgoldb/archive/2008/10/30/improving-microsoft-datagrid-sorting-performance-part-3。 aspx

许多人不使用 WPF datagrid 的默认 SortMemberPath,只是因为它在每条记录上使用 反射,这将大大降低排序过程的性能。

侯赛因

Loading data: 200k rows is a lot of data that no one (user) wants to see in one place. It will definitely reduce your UI user experience. So your best bet is to filter your data just to reduce the amount of it (for example do not show closed orders, just show the open ones). If you can't do so, you should use Virtualization. I didn't see any applications that use pagination in order to show data (Of course except in web). Most of the time it isn't such a good approach. But if you are talking about a type of data that is like search engines results you must use it. But keep in mind that most users won't exceed page 10 in search engines results.

Filtering: I would suggest doing it on your server side for such a huge amount of data (SQL Server here), or as I said first filter the whole 200k to reduce the amount on server side and then filter it (for user) in order to find something, on the client side. You might also find the following link helpful:

  1. http://www.codeproject.com/KB/WPF/DataGridFilterLibrary.aspx

Sorting: Again I would suggest server-client solution but you might also find following links helpful:

  1. http://blogs.msdn.com/b/jgoldb/archive/2008/08/26/improving-microsoft-datagrid-ctp-sorting-performance.aspx
  2. http://blogs.msdn.com/b/jgoldb/archive/2008/08/28/improving-microsoft-datagrid-ctp-sorting-performance-part-2.aspx
  3. http://blogs.msdn.com/b/jgoldb/archive/2008/10/30/improving-microsoft-datagrid-sorting-performance-part-3.aspx

Many people don't use default SortMemberPath of WPF datagrid just because it uses reflection on every single record and this will highly reduce the performance of the sorting process.

Hosein

风柔一江水 2024-11-07 20:54:13

这是一个非常好的数据虚拟化示例(不是 UI 虚拟化):

http://www.codeproject.com/KB/WPF/WpfDataVirtualization.aspx< /a>


尽管它不直接支持 LINQ IQueryable 对象,但您可以按原样使用此示例。当然,我现在正在努力改进它以直接使用 IQueryable 对象。我认为这并不难。

Here is a very good sample of Data Virtualization (Not UI Virtualization):

http://www.codeproject.com/KB/WPF/WpfDataVirtualization.aspx

Althogh it doesn't support the LINQ IQueryable objects directly but you can use this sample as it is. Of course I'm now wokring to improve it to work with IQueryable objects directly. I think it's not so hard.

番薯 2024-11-07 20:54:13

哇,200K 行数据量很大。寻呼听起来是个好主意。尝试确定每页需要多少行,例如 50 行。第一次显示屏幕时,仅显示前 50 行。然后为用户提供在页面之间移动的选项。

但这种方式排序可能会比较棘手。

虚拟化可能是另一种选择,遗憾的是,我还没有使用过虚拟化。

Wow, 200K rows is a lot of data. Paging sounds like a good idea. Try to decide how many rows per page you want, say 50. Upon showing the screen the first time, show only the first 50. Then give the user the option to move between pages.

Sorting might be trickier this way though.

Virtualization can be another option, sadly, I have yet to work with virtualization.

污味仙女 2024-11-07 20:54:13

有时您可能只有〜30个可见行要加载,并且如果这些行+任何列由于每个单元格的数量和复杂性(它是模板,或者它有多少个wpf元素)而加载起来很昂贵,则以上评论都没有真正有所作为。每一行都需要一段美好的时间来加载!

有用的是交错或延迟加载 UI 上的每一行,以便用户看到 ui 正在执行某些操作,而不是仅仅冻结约 10 秒以上。
为简单起见,假设数据网格 ItemSource="{Binding Rows}",并且 Rows 是 IEnumerable,其中 Row 是您创建的某个类:向 Row 添加属性 IsVisible (当然,不要忘记引发属性更改),

您可以做这样的事情:

private void OnFirstTimeLoad()
{
    Task.Factory.StartNew(() =>
    {
        foreach (var row in ViewModel.Rows)                                                
        {
            /*this is all you really need, 
              note: since you're on the background thread, make sure IsVisible executes on the UI thread, my utils method does just that*/
              myUtils.ExecuteOnUiThread(() => row.IsVisible = true);

              /*optional tweak: 
              this just forces Ui to refresh so each row repaint staggers nicely*/
              Application.Current.Dispatcher
                         .Invoke(DispatcherPriority.Background, (SendOrPostCallback) delegate { }, null);
         }
       });
}

哦,不要忘记在 XAML 中触发:

<DataGrid.ItemContainerStyle>
    <Style TargetType="{x:Type DataGridRow}">
        <Setter Property="Visibility" Value="{Binding Path=IsVisible, Converter={StaticResource BoolToVisibility}}"/>
      ........

Sometimes you may have only ~30 visible rows to load and if those rows + whatever columns are expensive to load due to their number and complexity of the each cell (it's template, or how many wpf elements it has), none of the above comments really make a difference. Each row will take it's sweet time to load!

What helps is to stagger or lazily load each row on the UI, so that the user sees that the ui is doing something rather than just freezing for ~10+ seconds..
For simplicity, assuming that the datagrid ItemSource="{Binding Rows}", and Rows is IEnumerable, where Row is some class you created : add a property IsVisible to Row (don't forget to raise property changed, of course)

you could do something like this:

private void OnFirstTimeLoad()
{
    Task.Factory.StartNew(() =>
    {
        foreach (var row in ViewModel.Rows)                                                
        {
            /*this is all you really need, 
              note: since you're on the background thread, make sure IsVisible executes on the UI thread, my utils method does just that*/
              myUtils.ExecuteOnUiThread(() => row.IsVisible = true);

              /*optional tweak: 
              this just forces Ui to refresh so each row repaint staggers nicely*/
              Application.Current.Dispatcher
                         .Invoke(DispatcherPriority.Background, (SendOrPostCallback) delegate { }, null);
         }
       });
}

oh, and don't forget to trigger in XAML:

<DataGrid.ItemContainerStyle>
    <Style TargetType="{x:Type DataGridRow}">
        <Setter Property="Visibility" Value="{Binding Path=IsVisible, Converter={StaticResource BoolToVisibility}}"/>
      ........
弥繁 2024-11-07 20:54:13

你的数据网格在滚动查看器中吗?因为它会渲染整个数据网格(所有行)。我遇到了类似的问题,删除滚动查看器解决了加载缓慢的问题。

Is your datagrid inside a Scrollviewer? Because it does the entire datagrid (all the rows) to be rendered. I had a similar problem and removing the scrollviewer solved the problem with the slow loading.

太阳哥哥 2024-11-07 20:54:13

您应该问的问题是:

  1. 用户是否愿意查看 200K 行数据?
  2. 对于用户来说多少数据过多?可能会提醒用户查询返回了太多行,并且您列出了前 1000 行,
  3. 这是否值得您花时间&如果用户不关注前 1000 行以外的内容,就需要花钱来编程分页、数据虚拟化等。

Question that you should be asking is:

  1. Are users groing to look through 200K rows of data?
  2. How much data is too much for the users? May be alert the user that the query returned too many rows and you are listing the first 1000
  3. Is it worth your time & money to program paging, Data Virtualization etc if users do not look beyond the first 1000 rows.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文