Search code examples
wpflistviewuwpgroupingcollectionviewsource

Grouping of items in ListView WPF


I have a ListView where I want to group the items based on a field of the item object. Below is the code I have:

<ListView ItemsSource="{x:Bind MyVM.CollectionOfClassA, Mode=OneWay}"
    <ListView.GroupStyle>
        <GroupStyle>
            <GroupStyle.HeaderTemplate>
                <DataTemplate>
                    <TextBlock FontSize="15" FontWeight="Bold" Text="{Binding DateTimePropertyOfClassA}"/>
                </DataTemplate>
            </GroupStyle.HeaderTemplate>
        </GroupStyle>
    </ListView.GroupStyle>
</ListView>

Is there something I am missing? I want to group the items based on the DateTime property of ClassA objects. Also, if there is no item for any particular day, I would still like to show that date with empty list under that group (for that day). How can I achieve it?

Edit: I am not able to use CollectionViewSource since my VM contains the collection of ClassA object (which is bound as item source to the listview) and I want to group the items based on one property of those ClassA objects. I am sure there is something I am missing out on. But I am not able to figure it out.


Solution

  • Here is the solution for anyone looking for it (thanks to the WPF masters out there https://social.msdn.microsoft.com/Forums/windowsapps/en-US/812ed260-e113-4a8b-9322-226ed56ac90c/grouping-of-items-in-listview-wpf?forum=wpdevelop&prof=required):

    public class ClassA
    {
        public DateTime DateTimePropertyOfClassA { get; set; }
    }
    
    public class MyVM
    {
        public MyVM()
        {
            //return a grouped collection:
            Grouped = from x in CollectionOfClassA group x by x.DateTimePropertyOfClassA into grp orderby grp.Key select grp;
        }
    
        public IList<ClassA> CollectionOfClassA { get; set; } = new List<ClassA>()
        {
                new ClassA(){ DateTimePropertyOfClassA = DateTime.Parse("2016-01-01")},
                new ClassA(){ DateTimePropertyOfClassA = DateTime.Parse("2016-03-01")},
                new ClassA(){ DateTimePropertyOfClassA = DateTime.Parse("2016-03-01")},
                new ClassA(){ DateTimePropertyOfClassA = DateTime.Parse("2016-03-01")},
                new ClassA(){ DateTimePropertyOfClassA = DateTime.Parse("2016-03-01")},
                new ClassA(){ DateTimePropertyOfClassA =DateTime.Parse("2016-06-01")}
        };
    
        public IEnumerable<object> Grouped { get; }
    }
    

    Xaml:

    <Page.Resources>
            <CollectionViewSource x:Name="cvs"
                                  IsSourceGrouped="True"
                                  Source="{x:Bind MyVM.Grouped, Mode=OneWay}"/>
    </Page.Resources>
    
    <StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <ListView ItemsSource="{Binding Source={StaticResource cvs}}">
            <ListView.GroupStyle>
                <GroupStyle>
                    <GroupStyle.HeaderTemplate>
                        <DataTemplate>
                            <TextBlock FontSize="15" FontWeight="Bold" Text="{Binding Key}"/>
                        </DataTemplate>
                    </GroupStyle.HeaderTemplate>
                </GroupStyle>
            </ListView.GroupStyle>
        </ListView>
    </StackPanel>