OXO
OXO

Reputation: 1098

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.

Upvotes: 2

Views: 3498

Answers (3)

Alexandar May - MSFT
Alexandar May - MSFT

Reputation: 10148

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

Upvotes: 5

H.A.H.
H.A.H.

Reputation: 3907

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

You speak as if this is something that has to remain like that. Obviously if you do not want to make groups, you wont be able to use grouping. So if you plan to keep it that way, I consider this question answered.

If you decide to create groups after all, the first thing you should do is bind to list of lists.

The outer list is simple. The inner list has property, that is used for grouping, and extends list.

To create those, you can modify the way you read them from the database, but if you do not want or know how to, and want to keep current reading, there is a way to use LINQ, in a way making another query for grouping, in similar way:

foreach( IGrouping<string, Model> group in NonGroupedList.GroupBy(s => s.Letter))
    MyGroups.Add(new MyGroup(group.key, group.ToList()));

Upvotes: 0

dreamboatDev
dreamboatDev

Reputation: 69

I hope this helps you. Download ListView example => Grouping: Github

enter image description here

Upvotes: 0

Related Questions