WPF Datagrid延迟加载

时间:2011-04-12 20:02:30

标签: c# .net wpf visual-studio-2008 wpfdatagrid

详细

  1. VS-2008 Professional SP1
  2. 版本.net 3.5
  3. 语言:C#
  4. 我有一个WPF Datagrid,它从Linq-sql查询Datacontext数据项加载。结果集包含大约200k行,加载它们,排序,过滤等非常慢。 什么是提高速度的简单方法?

    我看到的很多事情都是 Scrollview,数据虚拟化等人们也谈论分页,分析等

6 个答案:

答案 0 :(得分:4)

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

过滤:我建议您在服务器端执行此类大量数据(此处为SQL Server),或者正如我所说,首先过滤整个200k以减少服务器端的数量然后过滤它(为用户),以便在客户端找到一些东西。您可能还会发现以下链接有用:

  1. http://www.codeproject.com/KB/WPF/DataGridFilterLibrary.aspx
  2. 排序:我会建议服务器客户端解决方案,但您也可能会发现以下链接有用:

    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
    4. 许多人不使用WPF数据网格的默认SortMemberPath,因为它在每条记录上使用反射,这将大大降低排序过程的性能。

      Hosein

答案 1 :(得分:1)

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

  

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

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

答案 2 :(得分:0)

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

尽管如此,排序可能会更加棘手。

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

答案 3 :(得分:0)

有时你可能只有大约30个可见的行要加载,如果这些行+任何列的加载都很昂贵,因为它们的数量和每个单元格的复杂程度(它的模板,或它有多少个wpf元素),没有以上评论确实有所作为。每行都会花费很多时间加载!

有用的是错开或延迟加载UI上的每一行,以便用户看到ui正在做某事而不是冻结~10 +秒。 为简单起见,假设datagrid 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}}"/>
      ........

答案 4 :(得分:0)

您的datagrid是否在Scrollviewer中?因为它可以渲染整个数据网格(所有行)。我遇到了类似的问题,删除scrollviewer可以解决加载缓慢的问题。

答案 5 :(得分:-1)

您应该问的问题是:

  1. 用户是否正在浏览200K行数据?
  2. 用户的数据量是多少?可能会提醒用户该查询返回了太多行,而您正在列出前1000个
  3. 值得你花时间吗?如果用户不超出前1000行,则可以编程分页,数据虚拟化等。