WPF DataGrid loses virtualization when sorted by s

2019-06-10 09:10发布

问题:

I am using a WPF DataGrid that is bound to a custom ItemsSource that implements IList (and NOT IEnumerable). The custom ItemsSource performs data virtualization and only loads pages of items as needed. MyDataGrid actually inherits from DataGrid and overrides the handling of the DataGrid sort methods so that I can maintain data virtualization while sorting. I have UI Virtualization turned on for MyDataGrid.

When I run the application, MyDataGrid displays just fine, tells me I have roughly 20,000 items, and only asks my ItemsSource for the first 20 or so items. I then can click on column headers to sort various columns and again my ItemsSource only has to reload the first page of 40 items because MyDataGrid has asked to refresh only the first 20 or so.

BUT, when I click on my Last Name column to sort, MyDataGrid loses its UI Virtualization and asks my ItemsSource to load every single item even though it only needs the first 20 or so. I can watch as it asks for every single item by index (this[0]).

I've tried researching ICollectionView, UI Virtualization, and Data Virtualization and the only thing that I've read that seems it may apply is regarding multiple row selection (at DataGrid row request patterns with data virtualization I've set MyDataGrid's SelectionMode to Single so this shouldn't apply.

Another hint may be that, prior to sorting by Last Name, the first item in MyDataGrid has a last name that starts with the letter V (very late in the alphabet), and that I can actually sort the list in Descending order by last name without losing virtualization. The same thing happens with my Title column which has a first item that starts with the letter S. I don't have the problem with any of the other columns.

Any ideas?

回答1:

FIGURED IT OUT!!! Looking through the call stack, it appeared that the problem was happening during the MeasureOverride of the VirtualizingStackPanel and I noticed it was calling the SyncUniformSizeFlags method. So I then went into the default style for the DataGrid and set the RowHeight to a fixed amount and it no longer causes the problem.

So, it appears that the DataGrid can lose its virtualization when a fixed RowHeight is not set. Still don't know why opting to sort in ascending order by Last Name or Title caused it to want to resync the row heights, but I can work around that one.