WPF: DataGrid performance drops after Accessibility.dll gets loaded

37 Views Asked by At

When I work with a large dataset and lots of columns in a WPF DataGrid the scrolling is normally acceptable. But as soon as Accessibility.dll gets loaded the performance drops and it gets really slow and choppy when using the DataGrid. This happens when a ToolTip gets shown somewhere in the application. But it could also be a ComboBox , ContextMenu, or some other control as well. The moment the first ToolTip is shown I can see in the Output window the dll gets loaded:

'DataGridScrollPerformance.exe' (CLR v4.0.30319: DataGridScrollPerformance.exe): Loaded 'C:\windows\Microsoft.Net\assembly\GAC_MSIL\Accessibility\v4.0_4.0.0.0__b03f5f7f11d50a3a\Accessibility.dll'.

This is a WPF App using .NET Framework 4.8.

I found a similar question, but without answer:

https://stackoverflow.com/questions/60313755/ui-becomes-very-slow-to-show-tooltips-when-loading-massive-amount-of-data

To reproduce the issue I made a minimal WPF application with the classes below. When you compare scrolling from top to bottom before Accessibility.dll gets loaded and after it gets loaded there is a notable difference. I made 3 different controls to force Accessibility.dll to get loaded. A ToolTip, a ComboBox and a ContextMenu.

Model.cs

using System;

namespace DataGridScrollPerformance
{
    public class Model
    {
        public string Id { get; set; }
        public string Guid { get; set; }
        public DateTime DateForId { get; set; }
        public int Property1 { get; set; }
        public int Property2 { get; set; }
        public int Property3 { get; set; }
        public int Property4 { get; set; }
        public int Property5 { get; set; }
        public int Property6 { get; set; }
    }
}

MainWindow.xaml.cs

using System;
using System.Collections.Generic;
using System.Windows;

namespace DataGridScrollPerformance
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DataGrid.ItemsSource = GetDemoData();
        }

        private List<Model> GetDemoData()
        {
            var demoData = new List<Model>();
            var random = new Random();
            for (var i = 0; i < 1000; i++)
            {
                demoData.Add(new Model
                {
                    Id = i.ToString(),
                    Guid = Guid.NewGuid().ToString(),
                    DateForId = new DateTime(1900, 1, 1).AddDays(i),
                    Property1 = random.Next(0, 1000),
                    Property2 = random.Next(0, 1000),
                    Property3 = random.Next(0, 1000),
                    Property4 = random.Next(0, 1000),
                    Property5 = random.Next(0, 1000),
                    Property6 = random.Next(0, 1000),
                });
            }
            return demoData;
        }
    }
}

MainWindow.xaml

<Window x:Class="DataGridScrollPerformance.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="450" Width="800" WindowState="Maximized">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <StackPanel Grid.Row="0" Margin="5" HorizontalAlignment="Left" Orientation="Horizontal">
            <TextBox Width="200" ToolTip="This is a tooltip!" />
            <ComboBox Text="This is a ComboBox" Width="200" />
        </StackPanel>
        <DataGrid Grid.Row="1" Name="DataGrid" AutoGenerateColumns="False" VirtualizingPanel.ScrollUnit="Pixel">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Id" Binding="{Binding Id}"/>
                <DataGridTextColumn Header="Guid" Binding="{Binding Guid}"/>
                <DataGridTextColumn Header="Date for Id" Binding="{Binding DateForId, StringFormat={}{0:MM-dd-yyyy}}"/>
                <DataGridTextColumn Header="Property1" Binding="{Binding Property1}"/>
                <DataGridTextColumn Header="Property2" Binding="{Binding Property2}"/>
                <DataGridTextColumn Header="Property3" Binding="{Binding Property3}"/>
                <DataGridTextColumn Header="Property4" Binding="{Binding Property4}"/>
                <DataGridTextColumn Header="Property5" Binding="{Binding Property5}"/>
                <DataGridTextColumn Header="Property6" Binding="{Binding Property6}"/>
            </DataGrid.Columns>
            <DataGrid.ContextMenu>
                <ContextMenu>
                    <MenuItem Header="This is a MenuItem" Width="200" />
                </ContextMenu>
            </DataGrid.ContextMenu>
        </DataGrid>
    </Grid>
</Window>
0

There are 0 best solutions below