I have a WPF DataGrid which is displaying data sets with more than 60 columns and anything up to 10000s of rows. The DataGrid loads the complete datasets very quickly and handles them well.
colA colB colC colD colE ...
1 2 3 4 5
5 6 7 8 9
2 3 4 3 4
1 2 3 4 5
5 6 7 8 9
2 3 4 3 4
However the rows are split into groups. I need to display a group header that is a text string and to be able to expand/collapse the groups.
I can use grouping for the DataGrid which looks fine but is incredibly slow to initially display large groups.
colA colB colC colD colE ...
^ group title A
1 2 3 4 5
5 6 7 8 9
2 3 4 3 4
^ group title B
1 2 3 4 5
5 6 7 8 9
2 3 4 3 4
I can do the grouping myself externally to the DataGrid by adding an extra column with the group description in it. I can then collapse/expand any groups by changing the dataset provided to the grid. That is very fast, but it looks rubbish as it wastes a lot of space especially with long group titles.
group colA colB colC colD colE ...
group title A
1 2 3 4 5
5 6 7 8 9
2 3 4 3 4
group title B
1 2 3 4 5
5 6 7 8 9
2 3 4 3 4
What I want is the best of both worlds i.e. fast and pretty, to be able to display the data as if the DataGrid was grouping, but to do the grouping externally.
colA colB colC colD colE ...
^ Very long comment about the data ...
1 2 3 4 5
5 6 7 8 9
2 3 4 3 4
^ Another arbitrarily long comment...
1 2 3 4 5
5 6 7 8 9
2 3 4 3 4
Any idea how I can display my group headers that way?
This is an old question, however I add the answer here for future references:
Since .Net 4.5, Microsoft has added IsVirtualizingWhenGrouping
property. Setting this property of the DataGrid
to True
solves this issue.
<DataGrid VirtualizingPanel.IsVirtualizingWhenGrouping="True">
Source: This blog (Apparently this blog isn't available anymore)
I am working on this exact same problem now. The WPF Datagrid cannot virtualize when grouped as this is a limitation of the Expander control used to represent groups, which itself cannot be virtualized (as uses an ItemsPresenter, not ItemsControl).
A workaround is this (scroll down to Fake grouping with the help of the ViewModel). In this blog post the author implements groups in the viewmodel by having a hierarchy of data and group headers are rendered as a custom styled row. So its all rows - no expanders or groups per-se. This might allow you to virtualize and get the performance you need.
I'm investigating this now.
It probably loads fast initially because it is using Virtualization. This means it is only loading the visible items on the screen, not all 10000 rows and 60 columns. I am guessing that when Grouping it has to load everything which is why you are experiencing the slowdown.
To fix it, I would probably investigate creating your own control (with virtualization) and group the data beforehand. Perhaps bind an ItemsControl to the grouped data, include an expander, and when the group gets expanded get the data for that group only and load it in another itemscontrol. You can use Grid.IsSharedScopeSize and SharedSizeGroup to keep your column widths consistent.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With