WPF DataGrid doesn't seem to virtualize rows
I am working on an application where the bulk of my content is presented to users with inline WPF
DataGrid
. This is what mine looks like DataGrid
. I am not installing anything except RowDefinitions
in the parent Grid
.
<UserControl xmlns="blah blah blah">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<DataGrid x:Name="dgrMaterialCollection"
IsReadOnly="True"
ItemsSource="{Binding Path=MyObservableCollection, UpdateSourceTrigger=PropertyChanged}"
AutoGenerateColumns="True"
AutoGeneratingColumn="dgrMaterialCollection_AutoGeneratingColumn"
AutoGeneratedColumns="dgrMaterialCollection_AutoGeneratedColumns"
CanUserResizeColumns="True"
CanUserReorderColumns="True"
CanUserSortColumns="True"
EnableRowVirtualization="True"
EnableColumnVirtualization="True"
VirtualizingPanel.IsVirtualizingWhenGrouping="True"
VirtualizingPanel.VirtualizationMode="Standard"
VirtualizingPanel.IsVirtualizing="True"
SelectionMode="Single"
SelectionUnit="FullRow"
ScrollViewer.CanContentScroll="False"
RowHeaderWidth="0"
Grid.Row="0"
RowHeight="32"
RowDetailsVisibilityMode="Collapsed">
<DataGrid.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="DataGridStyle.xaml"/>
</ResourceDictionary.MergedDictionaries>
<!-- A few value converters -->
</ResourceDictionary>
</DataGrid.Resources>
<!-- Some Manually Declared Columns -->
</DataGrid>
<StackPanel Grid.Row="1">
<SomeTextBoxes/>
</StackPanel>
</Grid>
</UserControl>
When my application renders DataGrid
, there is approximately a 10-20 second delay depending on the size of the dataset. During this delay, the user interface is blocked. After loading the data grid, I can scroll through all several thousand items without any delay. When I say without delay, I mean to click on the scrollbar and move it up and down as quickly as humanly, without delaying the rendering of rows when scrolling. It looks like virtualization is not working and instead the datagrid creates all rows in one go, not while the user scrolls.
My Datagrid is nested in the following structure (spread across multiple xaml files). Additional ScrollViewers
, StackPanels
not or not. Just this.
<RibbonWindow>
<Grid>
<ContentControl> <!-- Populated via a DataTemplate and ContentTemplateSelector -->
<UserControl>
<UserControl>
<UserControl>
<Grid>
<Here is the DataGrid>
Some things I tried to speed up loading
- Explicitly set all column widths (shaved off about 10 seconds since boot)
- Disabled
AutoGenerateColumns
(doesn't matter). - Disabling styles set to
DataGrid's
RessourceDictionary
(no difference) - Load items to mine
ObservableCollection
on a background thread using async / await and other multi-threading strategies. This did not affect loading times. - Add items to the new
ObservableCollection
one and then set it to the databound property (so that no events are fired) - Adding items
ObservableCollection
one at a time (events are triggered each time you add) - Enabling and disabling virtualization does not affect boot time.
I know the delay is not due to padding ObservableCollection
. It starts after the collection is full and when it WPF
DataGrid
displays all rows / columns. I have virtualization enabled and it still takes forever. I am using .NET Framework 4.5.1 (so 4.6 s issue Virtualization
doesn't cause this). There are also long delays in sorting (using the built-in data sort) and resizing columns from the UI.
What am I missing here? Is there something I can do to make it work Virtualization
? What things can speed this up? If I know what Virtualization
works, then I can switch to a new strategy like paging or some kind of lazy loading. Another solution I would like to work with is one where the UI is not locked / frozen while all lines are displayed. That way, users could at least click on another thing while the rows are being added.
source to share