Ask a questionAsk a question
 

AnswerVery slow grouping

  • Thursday, August 31, 2006 8:27 AMPaul Shmakov Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    Hello!

    I have a problem with grouping in "ObservableCollection -> CollectionViewSource -> ListView" scenario.

    In a couple of words: Changes in grouping and is too slow! Moreover, scrolling in the grouped ListView is very slow as well.

    Here's an example (based on CollectionViewSource SDK sample - July CTP):

    FILE: Data.cs - just a collection (of 1000 items) of some domain specific objects (hotels in this case)

    using System.Windows;

    using System.Collections.ObjectModel;

     

    namespace SDKSample

    {

        public class Hotel

        {

            private string name;

            private string city;

            private string rating;

     

            public string Name

            {

                get { return name; }

                set { name = value; }

            }

     

            public string City

            {

                get { return city; }

                set { city = value; }

            }

     

            public string Rating

            {

                get { return rating; }

                set { rating = value; }

            }

     

            public Hotel(string name, string city, string rating)

            {

                this.name = name;

                this.city = city;

                this.rating = rating;

            }

        }

     

        public class Hotels : ObservableCollection<Hotel>

        {

            public Hotels()

            {

                string[] cities = { "Moscow", "New York", "Paris" };

                string[] ratings = { "Bad", "Good", "The best!" };

     

                System.Random rnd = new System.Random();

     

                for (int i = 0; i < 1000; i++)

                {

                    string city = cities[rnd.Next(cities.Length)];

                    string rating = ratings[rnd.Next(ratings.Length)];

     

                    Add(new Hotel("Hotel#" + i, city, rating));

                }

            }

        }

    }

    FILE: Window1.xaml  - CollectionViewSource, grouping buttons and the ListView in GridView mode

    <Window x:Class="SDKSample.Window1"

      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

      xmlns:src="clr-namespace:SDKSample"

      xmlns:dat="clr-namespace:System.Windows.Data;assembly=PresentationFramework"

      Title="Slow grouping sample">

     

      <Window.Resources>

     

        <src:Hotels x:Key="hotels"/>

     

        <CollectionViewSource Source="{StaticResource hotels}" x:Key="cvs">

          <CollectionViewSource.GroupDescriptions>

            <dat:PropertyGroupDescription PropertyName="City"/>

          </CollectionViewSource.GroupDescriptions>

        </CollectionViewSource>

     

      </Window.Resources>

      <DockPanel>

        <StackPanel Orientation="Horizontal" DockPanel.Dock="Top" Margin="10,10,10,10">

            <TextBlock Text="Group by: "/>

            <RadioButton Name="City" IsChecked="True" Checked="ChangeGrouping" Content="City"/>

            <RadioButton Name="Rating" Checked="ChangeGrouping" Content="Rating"/>

            <RadioButton Name="None" Checked="ChangeGrouping" Content="No grouping"/>

        </StackPanel>

     

        <ListView ItemsSource="{Binding Source={StaticResource cvs}}"

                  VirtualizingStackPanel.IsVirtualizing="True"

                  Name="lv">

          <ListView.GroupStyle>

            <x:Static Member="GroupStyle.Default"/>

          </ListView.GroupStyle>

     

          <ListView.View>

            <GridView>

              <GridViewColumn Header="Hotel" DisplayMemberBinding="{Binding Path=Name}"/>

              <GridViewColumn Header="City" DisplayMemberBinding="{Binding Path=City}"/>

              <GridViewColumn Header="Rating" DisplayMemberBinding="{Binding Path=Rating}"/>

            </GridView>

          </ListView.View>

     

        </ListView>

     

      </DockPanel>

    </Window>

    FILE Window1.xaml.cs - grouping code

    using System.Windows;

    using System.Collections.ObjectModel;

    using System.Windows.Data;

    using System.ComponentModel;

    using System.Windows.Controls;

     

    namespace SDKSample

    {

        public partial class Window1 : Window

        {

            private CollectionViewSource dataView;

     

            public Window1()

            {

                InitializeComponent();

                dataView = (CollectionViewSource)(this.Resources["cvs"]);

            }

     

            private void ChangeGrouping(object sender, RoutedEventArgs args)

            {

                if (dataView == null)

                    return;

     

                RadioButton buttonClicked = args.OriginalSource as RadioButton;

                string groupBy = buttonClicked.Name;

     

                // Avoid unnecessary updates

                if (dataView.GroupDescriptions.Count != 1 ||

                    ((PropertyGroupDescription)dataView.GroupDescriptions[0]).PropertyName !=

                       groupBy)

                {

                    using (dataView.DeferRefresh())

                    {

                        dataView.GroupDescriptions.Clear();

                        if (groupBy != "None")

                        {

                            PropertyGroupDescription groupDescription =

                                new PropertyGroupDescription();

                            groupDescription.PropertyName = groupBy;

                            dataView.GroupDescriptions.Add(groupDescription);

                        }

                    }

                }

            }

        }

    }

    That's all.

    Test #1

    Try to change grouping mode (for example, from "City" to "Rating"). It takes about 5 seconds (!) on my P4 2.8Gz 2Gb RAM machine (.NET 3 July CTP)!

    Test #2

    When the ListView is grouped by City or Rating try to scroll down it using Page Down key. Each page takes about 2 seconds!

    Now, change grouping to "No grouping" and try to scroll again - this time it scrolls fast. So, a grouping affects scrolling somehow.

    Question

    Why grouping and scrolling is so slow in this particular scenario? Is there any way to speed it up?

    Thanks in advance!

Answers

  • Thursday, August 31, 2006 12:27 PMMarc Laroche Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer
    The case you are encountering is a particularity of the ItemsControl/ListBox/ListView controls...

    Whenever a "GroupStyle" is set on the control, the panel that layouts the items changes from VirtualizingStackPanel to StackPanel (this is a hack in MS code)...

    Since UI Virtualization goes off, all of your 1000 items gets "realized" and this is the reason for the 5 seconds loading time... At the same time, when you scroll, the StackPanel have to calculate the new position of your 1000 items, hence the 2 seconds...

    Therefore, performance and grouping are not pairing togheter well in those controls... And there is currently no alternative to this.

All Replies

  • Thursday, August 31, 2006 12:27 PMMarc Laroche Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer
    The case you are encountering is a particularity of the ItemsControl/ListBox/ListView controls...

    Whenever a "GroupStyle" is set on the control, the panel that layouts the items changes from VirtualizingStackPanel to StackPanel (this is a hack in MS code)...

    Since UI Virtualization goes off, all of your 1000 items gets "realized" and this is the reason for the 5 seconds loading time... At the same time, when you scroll, the StackPanel have to calculate the new position of your 1000 items, hence the 2 seconds...

    Therefore, performance and grouping are not pairing togheter well in those controls... And there is currently no alternative to this.
  • Thursday, August 31, 2006 12:37 PMPaul Shmakov Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Hi Marcus,

    Thanks a lot for reply. I got an idea.

    I'd like to know - is the current behavior is "by design" and won't change OR it's just a bug/not implemented feature?

    Grouping is an essential feature of ListBox/ListView controls.

    Thanks
  • Thursday, August 31, 2006 1:55 PMPaul Shmakov Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Just found this bug on Microsoft Connect:

    https://connect.microsoft.com/feedback/ViewFeedback.aspx?FeedbackID=123998&SiteID=212

    Too bad, it could be a showstopper in my project.
  • Thursday, July 09, 2009 7:32 AMLuke R Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Marc,  any news on when Virtualization support will be supported when grouping within the ListView is enabled?  This issue has been around for a long time now and should have been fixed by now I would think.