Kohins
Kohins

Reputation: 337

Better performance from datagrid grouping

I have a DataGrid which I am using with an ICollectionView to group items in a large collection, 20k+ rows in some instances. I have used this approach before with varying success with showing all rows or virtualizing to create a more responsive page. In this instance I would like to virtualize as much as possible to keep the UI responsive. I have used the tips in this answer with little success to my issues. Helpful DataGrid Link

My main issue is a couple second lag on the DataGrid when loading the data into the ICollectionView View/Source, which I would like to minimize with the proper virtualization. Here is some of my code:

<DataGrid Margin="0,2,0,0" IsReadOnly="True" ItemsSource="{Binding DataView,IsAsync =True}" EnableRowVirtualization ="True" MaxWidth="2560" MaxHeight="1600"
              Grid.Row="2" SelectionMode="Extended" VirtualizingPanel.IsVirtualizingWhenGrouping="True" SelectionUnit="FullRow" SelectedItem="{Binding SelectedOutage}">
    <DataGrid.GroupStyle>
            <GroupStyle>
                <GroupStyle.ContainerStyle>
                    <Style TargetType="{x:Type GroupItem}">
                        <Setter Property="Margin" Value="0,0,0,5"/>
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate TargetType="{x:Type GroupItem}">
                                    <Expander IsExpanded="True" Foreground="{StaticResource Foreground}" Background="{StaticResource AlternatingBackground}">
                                        <Expander.Header>
                                            <TextBlock Text="{Binding Name}" Margin="5,0,0,0" Width="300"/>
                                        </Expander.Header>
                                        <ItemsPresenter />
                                    </Expander>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </GroupStyle.ContainerStyle>
            </GroupStyle>
        </DataGrid.GroupStyle>
        <!--Follows are DataGrid.ContextMenu and DataGridTextColumns with fixed widths-->
</DataGrid>

And c# items:

public ICollectionView DataView { get; set; }
private readonly ObservableCollection<EquipmentMonitorRow> equipment = new ObservableCollection<EquipmentMonitorRow>();

DataView = CollectionViewSource.GetDefaultView(equipment);
DataView.GroupDescriptions.Add(new PropertyGroupDescription("GroupName"));

equipment.Clear();
//Lag is during this item adding.
equipment.AddRange(data);

So hopefully I'm missing some virtualization or maybe I can add the items differently or something. Any help would be appreciated. Thanks.

Upvotes: 2

Views: 2860

Answers (2)

Kohins
Kohins

Reputation: 337

Changing my ObservableCollection source to a List source solved the initial load lag.

private readonly List<EquipmentMonitorRow> equipment = new List<EquipmentMonitorRow>();

Also using a combination of VirtualizingPanel properties I achieved the best virtualization. Specifically if I omitted VirtualizingPanel.IsVirtualizingWhenGrouping="True" then the application lagged for almost a minute before showing anything in my DataGrid. The scrolling was a lot better without virtualization but the initial load was unacceptable in my case.

VirtualizingPanel.IsVirtualizingWhenGrouping="True" VirtualizingPanel.ScrollUnit ="Item" VirtualizingPanel.VirtualizationMode="Recycling"

Thanks for the help.

Upvotes: 4

Rohit Vats
Rohit Vats

Reputation: 81253

Datagrid by default support UI virtualization but as soon as you apply grouping on ICollectionView, UI virtualization will be turned off.

You can refer to MSDN sample which basically flattens the grouped list which supports virtualization.


UPDATE for comment:

This doesn't specifically mention a collectionview but seems there is virtualization

From the link:

In a normal WPF ItemsControl that virtualizes, such as ListBox or ListView, virtualization turns off when you turn grouping on.

And DataGrid derives from ItemsControl only, hence UI virtualization is turned off on grouping.

Upvotes: 1

Related Questions