WPF DataGrid is very slow to render

Viewed 46810

I have tried using both a customized DataGrid as well as the stock one in WPF. I have tried populating them manually as well as through bindings. In both cases they are slow.

I have a scenerio where the user clicks on a button and a DataGrid appears with appropriate data. Currently I am in proof of concept mode and just using sample data. I have a DataSet with a table that has 10 rows in it.

If I don't attach any data to the DataGrid when I click the button the empty DataGrid displays pretty much instantly, a user cannot perceive a delay. As soon as I add 10 rows of data, for 6 columns, the delay is about 2 seconds, very noticable to the user.

I even tried filling with empty data, just to get an empty grid to appear and it is equally as slow.

for (int i = 0; i < 10; i++)
    _dataGrid.Items.Add("");

I put a timer to count the ticks from when the button is clicked to when all of the code is executed to draw the DataGrid and it is around 20 milliseconds, so the code executes very fast, but on the screen is where the big lag is. I tried a GridView and it renders much fast on the screen.

I have heard various reports of slow DataGrid drawing with complex scenarios and using 1000's of rows, but this is as simple as it gets, 6 columns by 10 rows filled with empty data.

For readonly display is GridView an equally viable option to the DataGrid?


Update

Here is the creation of my columns.

                DataGridTextColumn column = new DataGridTextColumn();
                column.ColumnWidthChanged += new ColumnWidthChangedEventHandler(column_ColumnWidthChanged);

                column.Header = entity.GetPropertyValue("ColumnLabel");
                column.Binding = new Binding(entity.GetPropertyValue("Tag"));
                column.Width = new DataGridLength(entity.GetPropertyDouble("DisplaySize"));
                _dataGrid.Columns.Add(column);

This is a how I bind the DataSet with 10 rows in it.

                _dataGrid.ItemsSource = ds.Tables[0].DefaultView;
                _dataGrid.DataContext = ds.Tables[0];

Not sure what I can do differently.

11 Answers

Well a little bit adding more (i know its very old topic, but still it helps someone)...

I tried

EnableColumnVirtualization="True" VirtualizingPanel.VirtualizationMode="Recycling"
EnableRowVirtualization="True" 

for DataGrid(AutoGenerateColumns="True") binding to DataTable.DefaultView() and No effect on speed, it was still horrible for Speed as well as for navigation between rows. Than, I came up with solution to set Fixed Height and Width of DataGrid. Additionally I also set

RowHeight="23" 
ScrollViewer.HorizontalScrollBarVisibility="Visible"
ScrollViewer.VerticalScrollBarVisibility="Visible"

This makes my page fill very fast... Instead of 2 min, now it takes hardly 10-12 seconds.

Hope it helps someone.

Note: I am using .Net 4.5

My problem was that I had ScrollViewer.CanContentScroll="False" set on my DataGrid. This disables virtualization all together for the DataGrid. More info about this can be found here:

https://stackoverflow.com/a/3724695/4383302

If you have row definition like belove:

 <Grid.RowDefinitions>
        <RowDefinition x:Name="topRow" Height="*"/>
        <RowDefinition x:Name="mainRow" Height="*"/>
        <RowDefinition x:Name="dataGridRow" Height="*"/>
    </Grid.RowDefinitions>

You must be carefull! Such as if your Datagrid in one of these rows then it will be resized for every row over and over again. If you have 1000 rows then it will be resized 1000 times your Datagrid!

Let us tell that your Datagrid is in 3rd RowDefinition then what I suggest is you to change the code on this way.

     <Grid.RowDefinitions>
        <RowDefinition x:Name="topRow" Height="*"/>
        <RowDefinition x:Name="mainRow" Height="*"/>
        <RowDefinition x:Name="dataGridRow" Height="400"/>
    </Grid.RowDefinitions>

Of course you can also change "400" how you wish.

Related