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:
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.
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.
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.
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);
}
});
}
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);
}
});
}
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.
发布评论
评论(6)
加载数据:200k 行是大量数据,没有人(用户)愿意在一个地方看到。它肯定会降低你的 UI 用户体验。因此,最好的选择是过滤数据以减少数据量(例如,不显示已关闭的订单,仅显示未关闭的订单)。如果你不能这样做,你应该使用虚拟化。我没有看到任何使用分页来显示数据的应用程序(当然除了网络)。大多数时候这并不是一个好的方法。但如果您谈论的是一种类似于搜索引擎结果的数据,则必须使用它。但请记住,大多数用户在搜索引擎结果中不会超过第 10 页。
过滤:对于如此大量的数据(这里是SQL Server),我建议在服务器端执行此操作,或者正如我所说,首先过滤整个200k以减少服务器端的数据量,然后再过滤它(对于用户)为了在客户端找到某些东西。您可能还会发现以下链接很有帮助:
排序: 我再次建议服务器客户端解决方案,但您可能还会发现以下链接很有帮助:
许多人不使用 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:
Sorting: Again I would suggest server-client solution but you might also find following links helpful:
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
这是一个非常好的数据虚拟化示例(不是 UI 虚拟化):
尽管它不直接支持 LINQ IQueryable 对象,但您可以按原样使用此示例。当然,我现在正在努力改进它以直接使用 IQueryable 对象。我认为这并不难。
Here is a very good sample of Data Virtualization (Not UI Virtualization):
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.
哇,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.
有时您可能只有〜30个可见行要加载,并且如果这些行+任何列由于每个单元格的数量和复杂性(它是模板,或者它有多少个wpf元素)而加载起来很昂贵,则以上评论都没有真正有所作为。每一行都需要一段美好的时间来加载!
有用的是交错或延迟加载 UI 上的每一行,以便用户看到 ui 正在执行某些操作,而不是仅仅冻结约 10 秒以上。
为简单起见,假设数据网格 ItemSource="{Binding Rows}",并且 Rows 是 IEnumerable,其中 Row 是您创建的某个类:向 Row 添加属性 IsVisible (当然,不要忘记引发属性更改),
您可以做这样的事情:
哦,不要忘记在 XAML 中触发:
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:
oh, and don't forget to trigger in XAML:
你的数据网格在滚动查看器中吗?因为它会渲染整个数据网格(所有行)。我遇到了类似的问题,删除滚动查看器解决了加载缓慢的问题。
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.
您应该问的问题是:
Question that you should be asking is: