简体   繁体   中英

Improve WPF DataGrid performance

In my .NET 3.5 WPF Application, I have a WPF DataGrid which will be populated with 500 columns and 50 rows. The performance of App is very very poor in scrolling, or when I do DataGrid.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?

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!

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

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.

Maybe try this instead of loading all 50 rows at once

http://www.codeproject.com/Articles/34405/WPF-Data-Virtualization

Step 1: 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: 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM