3
votes

I have a WPF DataGrid with almost 8000 Rows. It's taking approx. 25 seconds to load. Any clues how do I improve its performance?

This Grid has 3 static ButtonType Columns and other columns are dynamic. I fetch data inside a list and assign it to the ItemsSource property of the DataGrid on CodeBehind.

Here is the XAML code:

<UserControl x:Class="TransportApp.Views.CommonScreen.SideBar.DetailsGrid"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:mui="http://firstfloorsoftware.com/ModernUI"
             xmlns:sys="clr-namespace:System;assembly=mscorlib"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid Margin="5,0,0,0" VirtualizingStackPanel.IsVirtualizing="True">
        <Grid.RowDefinitions>
            <RowDefinition Height="60"/>
            <RowDefinition Height="1*"/>
            <RowDefinition Height="5" />
        </Grid.RowDefinitions>
        <Grid Grid.Row="0"  HorizontalAlignment="Left">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="1*"/>
                <ColumnDefinition Width="120"/>
                <ColumnDefinition Width="30"/>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="30"/>
                <RowDefinition Height="30"/>
            </Grid.RowDefinitions>
            <Label Name="DisplayHeader" Grid.Row="0" Content="Information" VerticalAlignment="Center" FontSize="20" />
            <DatePicker Name="dtGridFilterDate" Grid.Column="1" Grid.Row="0" Margin="4" SelectedDate="{x:Static sys:DateTime.Now}"/>
            <mui:ModernButton Name="Cmd_Refresh" Grid.Column="2" Grid.Row="0" ToolTip="Click to Refresh View" IconData="{StaticResource RefreshIconData}" EllipseStrokeThickness="2" EllipseDiameter="26" IconHeight="15" IconWidth="15" Click="Cmd_Refresh_Click"/>
            <DockPanel Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="1">
                <Label FontWeight="Bold" DockPanel.Dock="Left" Name="lblFilter" Content="Filter" VerticalAlignment="Center"/>
                <TextBox DockPanel.Dock="Right" Margin="4" HorizontalAlignment="Stretch" Grid.Column="1" VerticalContentAlignment="Center" Name="filterBox1"/>
            </DockPanel>
            <mui:ModernButton Name="cmdSearch" Grid.Column="2" Grid.Row="1" ToolTip="Click to Search" IconData="{StaticResource SearchData}" EllipseStrokeThickness="2" EllipseDiameter="26" IconHeight="11" IconWidth="11" Click="cmdSearch_Click"/>
        </Grid>

        <DataGrid Name="DG_Details" Grid.Row="1" 
                      AutoGenerateColumns="True" IsReadOnly="True" 
                      CanUserAddRows="False" CanUserDeleteRows="False" 
                      SelectionMode="Single" EnableRowVirtualization="True"
                      VirtualizingStackPanel.IsVirtualizing="True"
                      AutoGeneratingColumn="DG_Details_AutoGeneratingColumn" 
                      HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Disabled">
            <DataGrid.Columns>
                <DataGridTemplateColumn x:Name="dgEditColumn">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <mui:ModernButton Name="Cmd_Edit" Click="Cmd_Edit_Click" ToolTip="Edit" IconData="{StaticResource EditIconData}" EllipseStrokeThickness="2" EllipseDiameter="20" IconHeight="10" IconWidth="10"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
                <DataGridTemplateColumn x:Name="dgDeleteColumn">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <mui:ModernButton Name="Cmd_Delete" Click="Cmd_Delete_Click" ToolTip="Delete" IconData="{StaticResource DeleteIconData}" EllipseStrokeThickness="2" EllipseDiameter="20" IconHeight="10" IconWidth="10"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
                <DataGridTemplateColumn x:Name="dgPrintColumn" Visibility="Hidden">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <mui:ModernButton Name="Cmd_Print" Click="Cmd_Print_Click" ToolTip="Re-Print document" IconData="{StaticResource PrintIconData}" EllipseStrokeThickness="2" EllipseDiameter="20" IconHeight="10" IconWidth="10"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</UserControl>

Data Loading Logic

var customerList = (from c in context.Customers
                                            where c.IsDeleted == false
                                            select new
                                            {
                                                FirstName = c.FirstName,
                                                LastName = c.LastName,
                                                Phone = c.Phone,
                                                CustomerId = c.CustomerId
                                            }).ToList();

                            DG_Details.ItemsSource = customerList;
                            DG_Details.Items.Refresh();

A thing to note here is, DataGrid's performance is great after loading. No lag at all. I am using a Core i5 machine with 4 GB RAM and 512 MB graphics card.

Please let me know if any optimizations can be done in this code.

1
Don't use a DataGrid. Use ListView / GridView. - paparazzo
@Blam: I could spot ListView in the ToolBox but no GridView - Nilesh Barai
The problem might be the loading logic and not the datagrid, because the datagrid is using virtualisation. So why don't you show the loading logic instead of the xaml ? - Philip Stuyck
@PhilipStuyck: Updated the post :) I am using entity framework in my project. - Nilesh Barai
@Blam: This ListView/GridView approach is not bad. Atleast its loading data in 1 sec. Just that I will have to modify lot many things :( - Nilesh Barai

1 Answers

3
votes

DataGrid does a lot of stuff but it also has a lot of overhead.

ListView / GridView is more work but is faster.