Search code examples
xamldata-bindingmaui

Grouped CollectionView in .NET MAUI


I have a ObservableRangeCollection Persons in my ViewModel which is bound in XAML to a CollectionView via ItemsSource. The DataTemplate is of Type Person, so they can be displayed.

Currently, I don’t know how I would do the grouping which is provided via IsGrouped-Option in the CollectionView.

How would I introduce the different Groups based on the first Letter of the Name of a Person, so that I have a Group „A“ with all Persons whose Name starts with letter „A“.

My ObservableRangeCollection is filled from values of a SQLite database which does not have groups, just the details for a Person.


Solution

  • If you want to group the person based on first character of the name of the Person, you can refer to the sample code below:

    SAMPLE CODE:

    XAML:

        <CollectionView ItemsSource="{Binding Persons}" IsGrouped="True"> 
    
            <CollectionView.GroupHeaderTemplate>
    
                <DataTemplate>
    
                    <Label FontSize="18" FontAttributes="Bold" BackgroundColor="Gray" Text="{Binding Name}" />
    
                </DataTemplate>
    
            </CollectionView.GroupHeaderTemplate>
    
            <CollectionView.ItemTemplate>
    
                <DataTemplate>
    
                    <VerticalStackLayout>
    
                        <Label
    
                           Text="{Binding Name}"
    
                           FontAttributes="Bold" />
    
                    
                    </VerticalStackLayout>
    
                </DataTemplate>
    
            </CollectionView.ItemTemplate>
    
        </CollectionView>
    
    

    VIDEMODEL:

    
    public class MainPageViewModel 
        {
    
            public List<Person> origin_list { get; set; } = new List<Person>();
    
            public List<Grouped_list> Persons { get; set; } = new List<Grouped_list>();
    
    
    
            public MainPageViewModel()
            {
    
               //Pseudo data, you may retrieve the data from database and assign to it
                origin_list.AddRange(new List<Person> {
    
                   new Person("Allan", "Male"),
                    new Person("Alex", "Male"),
                    new Person("Klay", "Male"),
                    new Person("Kate", "Female"),
                    new Person("Bob", "Male"),
                    new Person("Besley", "Male"),
                    new Person("John", "Male"),
                    new Person("Fiona", "Female")
    
                });
    
                //Group by the first letter
                 var dict = (origin_list.OrderBy(x=>x.Name)).GroupBy(o => o.Name.Substring(0,1)).ToDictionary(g => g.Key, g => g.ToList());
    
                foreach(KeyValuePair<string, List<Person>> item in dict)
                {
    
                    Persons.Add(new Grouped_list(item.Key, new List<Person>(item.Value)));
                }
    
    
            }
    
           
        }
    
    

    Grouped_list.cs

        public class Grouped_list : List<Person> 
        {
    
            public string Name { get; set; }
    
            public Grouped_list(string name, List<Person> person):base(person)
            { 
                Name = name;
            
            }
        }
    
    

    MODEL:

    
        public class Person 
        {
    
            public string Name { get; set; }
    
            public string Gender { get; set; }  
    
            public Person(string name, string gender)
            {
                
                Name = name;
                Gender = gender;
            
            }
    
        }
    

    OUTPUT:

    enter image description here