1
votes

I know that DataGrid supports virtualization, so it creates grid cells only for visible rows. However, this seems to work only if the DataGrid is constrained in size.

In my scenario, a DataGrid is placed inside a scroll-viewer, like so

<ScrollViever>
    <StackPanel>

        <more elements .../>

        <DataGrid ... />

        <more elements .../>

    </StackPanel>
</ScrollViever>

This seems to break virtualization. In cases where the DataGrid should display a large number of items, the visual tree becomes very very large, even before scrolling down in the outer ScrollViewer.

Is there any way to prevent DataGrid from pre-creating all cells and rather have them created as the ScrollViewer is scrolling down?

EDIT: basically the page hosting this should be like a web page with some text at the top, a large table and some more text at the bottom. Instead of a dockview where top/bottom is always visible and just the grid is scrolled, the entire page should scroll. The setup achieves this, but suffers from everything being pre-created.

ANOTHER EDIT: Is there a way to detect that a particular row of the datagrid was scrolled into view? The typical lazy-loading articles use the datagrid's scrollviewer to add further items to the grid, which does not work here.

2
VirtualisingStackPanel?Craig Graham
But will VirtualizingStackPanel (as DataGrid's parent) cause the DataGrid to only generate its visible children? My understanding is that VirtualizingStackPanel will create ITS children on demand, which means as soon as the first top pixel of the DataGrid becomes visible, the ENTIRE DataGrid would be created? Or am I missing something?user1211286
Just tested: ScrollViewer-VirtualizingStackPanel-DataGrid does not solve the problem. DataGrid will still pre-generate all its rowsuser1211286
Ah well, it was a thought. I don't know a solution that keeps your extra elements in the StackPanel and avoids the DataGrid presenting its own scrollbar. The StackPanel's telling its children they have infinite height to use, so of course the DataGrid uses it. If it were me, next thing I'd try is having the DataGrid height constrained to the height of the StackPanel, hide both scrollbars, create a new scrollbar and bind that to something that controls the scroll positions of both the StackPanel and the DataGrid in a way that makes it look right. Complicated.Craig Graham

2 Answers

1
votes

Yes, you sort of answered your own question. If you place DataGrid inside ScrollViewer or StackPanel or any control that does not pass fix constraint to DataGrid it will break the virtualization in DataGrid.

You can fix this by giving DataGrid.Width and DataGrid.Height fix values.

You need to know those fix values for the virtualization. Virtualization needs fix ancestors.

Here is how you can give DataGrid fix size:

Simply bind Height/Widht to ScrollViewer or Grid.

<Grid x:Name="grid" >
   <ScrollViever>
       <StackPanel>

           <more elements .../>

           <DataGrid Width={Binding ElementName=grid, Path=Width..} Height={Binding ElementName...} />

           <more elements .../>

       </StackPanel>
   </ScrollViever>
<Grid>

That would be it :)

0
votes

Don't place it in a ScrollViewer, it will stretch as long as it desires in there, which will be its whole size.