xamllayoutmauicollectionviewmaui-collectionview

how to implement a .Net Maui CollectionView layout with vertical groups and horizontal items


i am trying to achieve a certain look within an application that shows items in a categorized way. From what i have learned is that the CollectionView allows us to exactly do this and i have successfully used it in various layouts. The problem is that there is exactly one layout that i am trying to achieve that i could not find described anywhere and hence need help/guidance with.

The CollectionView allows us to go for either a grid or linear layout and allows us to have grouping on objects. What i want to achieve is that the items of a group are shown as a linear horizontal collection while the categories are put one after another in a vertical way. (like shown in the amazing drawing attached).

epic deisgn

I have tried all possible combinations of the CollectionView (that i know of) and could not achieve this and thus am pondering whether at this point i would have to create this thing entirely manually or to have simply multiple CollectionView instances be created for each Category.

Any help would be appreciated. P.S: quiet new to .Net maui and mobile dev. but do have xaml knowledge.

I have tried to have one main collection view with isgrouped=true and a groupheaderlayout. then as item template i tried to create an another collectionview which takes the group again and works as a normal horizontal collectionview but it did not work.


Solution

  • I have managed to do it by doing the following:

    1. in the ItemsGroupModel declare a list of the same object type and populate it with the original one.
    public class AnimalsCategory : List<Animal>
    {
        public string GroupName { get; set; }
        public List<Animal> Animals { get; set; }
        public AnimalsCategory(string groupName, List<Animal> animals, string) : base(animals)
        {
            Animals = new List<Animal>(animals);
        }
    }
    
    1. The ViewModel is quiet the basic one and follows the recommended .Net Maui style (Note: i am using the Mvvm Toolkit for the ObservableProperty and sitting the property's value and not the fields!)
    public partial class AnimalsViewModel
    {
        [ObservableProperty]
        List<ShopItemsCategory> categories;
        
        public AnimalsViewModel(DataService ds)
        {
            Categories = ds.GetAnimalsInCategories();
        }
    }
    
    1. I made sure to access the newly defined property "Animals" in the XAML inside the sub-list.
    <RefreshView Grid.Row="1">
      <ScrollView>
          <CollectionView ItemsSource="{Binding Categories}">
              <CollectionView.ItemTemplate>
                  <DataTemplate x:DataType="model:AnimalsCategory ">
                      <StackLayout Orientation="Vertical">
                          <Label Text="{Binding GroupName}" FontAttributes="Bold" FontSize="28"/>
                          <CollectionView ItemsSource="{Binding Animals}" ItemsLayout="HorizontalList" Background="Transparent" Margin="5">
                              <CollectionView.ItemTemplate>
                                  <DataTemplate x:DataType="model:Animal">
                                      <Frame CornerRadius="20"
                                                    Margin="5,5,5,5"
                                                    HasShadow="True"
                                                    BackgroundColor="#FEF6FF"
                                                       WidthRequest="150"
                                                       HeightRequest="200">
                                          <StackLayout Orientation="Vertical" 
                                               Grid.Row="1" Margin="0,0,0,0">
                                              <Image Source="{Binding Image}" 
                                                Grid.Row="0" HeightRequest="60" 
                                                 WidthRequest="60" 
                                                 Margin="0,0,0,5"/>
                                              <Line Stroke="LightGray" X2="300" 
                                                StrokeThickness="2"/>
                                              <Label Text="{Binding Name}" > 
                                                Margin="0,5,0,0" 
                                                 FontAttributes="Bold" 
                                                  VerticalOptions="Center"
                                                 HorizontalOptions="Center"/>
                                               <Label Text="{Binding > 
                                            Description}" Margin="0,10,0,0"/>
                                          </StackLayout>
                                      </Frame>
                                  </DataTemplate>
                              </CollectionView.ItemTemplate>
                          </CollectionView>
                      </StackLayout>
                  </DataTemplate>
              </CollectionView.ItemTemplate>
          </CollectionView>
      </ScrollView>
    </RefreshView>