Improve WPF DataGrid performance
Solution 1
There are a few options you can turn on to help you on your DataGrid object
EnableColumnVirtualization = true
EnableRowVirtualization = true
These two are the main ones I think might help. Next try making your binding async
ItemsSource="{Binding MyStuff, IsAsync=True}"
And lastly, I've heard that setting a maximum height and width can help even if it above the max screen size, but I didn't notice a difference myself (claim had to do with auto size measuring)
MaxWidth="2560"
MaxHeight="1600"
Also never put a DataGrid
in a ScrollViewer
, because you will essentially lose virtualization. Let me know if this helps!
Solution 2
Check if you have property ScrollViewer.CanContentScroll
set False
.
Setting this property to false disables the virtualization in a way will degrade the performance of your Data-grid. For more clarification refer this CanContentScroll
Solution 3
Set the DataGrid.RowHeight
value and that will make a huge difference.
I know this is a really old question, but I just came across it, and this was the biggest difference on my end. My default height was 25.
Solution 4
Step 1: From 2 minutes to 10 seconds
This answer (Set ScrollViewer.CanContentScroll to True) put me on the right track. But I need it to be set to false
. To set it to true
when I'm doing my refresh I wrote this two methods.
internal static void DataGridRefreshItems(DataGrid dataGridToRefresh)
{
/// Get the scrollViewer from the datagrid
ScrollViewer scrollViewer = WpfToolsGeneral.FindVisualChildren<ScrollViewer>(dataGridToRefresh).ElementAt(0);
bool savedContentScrollState = scrollViewer.CanContentScroll;
scrollViewer.CanContentScroll = true;
dataGridToRefresh.Items.Refresh();
/// Was set to false, restore it
if (!savedContentScrollState)
{
/// This method finishes even when the update of the DataGrid is not
/// finished. Therefore we use this call to perform the restore of
/// the setting after the UI work has finished.
Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() => SetScrollViewerCanContentScrollFalse(scrollViewer)), DispatcherPriority.ContextIdle, null);
}
}
private static void SetScrollViewerCanContentScrollFalse(ScrollViewer scrollViewer)
{
scrollViewer.CanContentScroll = false;
}
This is the method I use to get the VisualChildren:
public static IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
{
if (depObj != null)
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
if (child != null && child is T)
{
yield return (T)child;
}
foreach (T childOfChild in FindVisualChildren<T>(child))
{
yield return childOfChild;
}
}
}
}
After this my refresh of 50.000 new items lasts only 10 seconds unlike 2 Minutes and consumes only 2 MB of RAM instad of 4 GB before.
Step 2: From 10 seconds to 0.5 seconds
For testing I disabled all of my IValueConverter
and implemented properties which I bind directly. Without the converters the DataGrid refreshes immediately. So I left it.
Comments
-
Kishor over 2 years
In my
.NET 3.5
WPF
Application, I have aWPF
DataGrid
which will be populated with 500 columns and 50 rows. The performance of App is very very poor in scrolling, or when I doDataGrid.Items.Refresh()
or in selecting rows.Actually App will take around 20 sec to Update Layout.
Layout_Updated()
event will trigger after 20 sec.If I reduce the columns to 50 or less, App will be very responsive. As per my findings performance is directly related to column count.
How do I improve the
DataGrid
performance? -
Kishor over 11 yearsThanks for suggestions. But my requirement to have 500 columns at once.
-
Constanta over 11 yearswell you said scrolling so I thought you don't display all rows at once (how do you do that anyway with 500 cols) The idea with data virtualization is that you load a certain number to populate your grid and then remove and replace rows as you scroll
-
Scott over 11 yearsI don't think EnableColumnVirtualization and EnableRowVirtualization are available until .NET 4.0. So the OP would need to upgrade from 3.5 before looking into the first suggestions.
-
Alan over 11 years@Scott Well that could be a reasonable solution. To the OP, why are you using .NET 3.5? .NET 4.0 is available on XP SP3 and many 3rd party libraries already require .NET 4.0 if you want to use them.
-
Kelly about 11 yearsI would also make your columns a fixed width.
-
testpattern over 10 years@Alan I'm curious as to how you go about having a large data grid that avoids being inside a ScrollViewer?
-
Alan over 10 years@testpattern The datagrid scrolls on its own, you just don't want to put it in your own ScrollViewer external to the DataGrid otherwise you'll lose virtualization of controls.
-
BENN1TH about 9 yearsI set my MaxHeight to 800 as a i had two scroll bars showing, maybe cause i had the grid wrapped in dockpanel but that fixed the (scrollbar) issue now i can load 1000+ items from XML into datagrid easily,fast and async without a slow render of the grid! thx
-
Vikas almost 9 yearsAmazing. I wonder why other threads never talked about this Enable Row and Column Virtualization. Thanks a ton.
-
Admin almost 7 yearsI am suprised people adding ScrollViewer to DataGrid. Could that be previous version of wpf datagrid does not support scrolling?
-
Siva Gopal over 5 yearsDefinitely worth giving a try! And in fact they improved the performance a lot for me. Thanks @Alan
-
Zeyad over 4 yearsSetting the MaxHeight made a significant improvement. Thank you very much. Also setting MaxWidth made a slight improvement as well. I was going crazy until I found this solution. Thank you.