Search This Blog

Thursday 7 May 2020

Grouped StackLayout In Xamarin Form (Xamarin Form Binding Grouped Data to Stack Layout).

Grouped StackLayout In Xamarin Form





The benefit of StackLayout Binding Compare to ListView Binding:
  • No need to worry about setting the height of stack layout (It automatically set the height as per content).
  • You can use the Stack Layout inside ScrollView.
  • As StackLayout does not have an inbuilt scrolling mechanism, So no need to worry about disabling the Scrolling.

Design Side
MainPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             x:Class="TestMobileApp.MainPage">
 
    <StackLayout Margin="10" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
        <ScrollView>
        <!-- Place new controls here -->
            <StackLayout BindableLayout.ItemsSource="{Binding Employees}">
                <BindableLayout.ItemTemplate>
                    <DataTemplate>
                        <StackLayout>
                            <!-- bind the header info-->
                            <StackLayout>
                                <Label Text="{Binding Header}" FontSize="15"   FontAttributes="Bold" />
                            </StackLayout>
                            <!-- bind the details-->
                            <StackLayout BindableLayout.ItemsSource="{Binding .}">
                                <BindableLayout.ItemTemplate>
                                    <DataTemplate>
                                        <Label Text="{Binding FullName}" />
                                    </DataTemplate>
                                </BindableLayout.ItemTemplate>
                            </StackLayout>
                            <BoxView HeightRequest="1" BackgroundColor="Gray" />
                        </StackLayout>
                    </DataTemplate>
                </BindableLayout.ItemTemplate>
            </StackLayout>
        </ScrollView>
    </StackLayout>
</ContentPage>

Code Behind:
MainPage.Xaml.cs
using System.ComponentModel;
using TestMobileApp.ViewModel;
using Xamarin.Forms;
namespace TestMobileApp
{
    // Learn more about making custom code visible in the Xamarin.Forms previewer
    // by visiting https://aka.ms/xamarinforms-previewer
    [DesignTimeVisible(false)]
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
            //Set the ViewModel Reference here
            this.BindingContext = new MainPageViewModel();
        }
    }
}

Note: Create The EmployeeHeaderInfo Class that inherit the EployeeDetails 
Models:
EmployeeHeaderInfo.cs
using System.Collections.ObjectModel;
namespace TestMobileApp.Model
{
    public class EmployeeHeaderInfo : ObservableCollection<EmployeeDetails>
    {
        public string Header { get; set; }
    }
}

EmployeeDetails.cs
namespace TestMobileApp.Model
{
    public class EmployeeDetails
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string FullName { get { return FirstName + ", " + LastName; } }
 
    }
}


ViewModel:
MainPageViewModel.cs
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using TestMobileApp.Model;
 
namespace TestMobileApp.ViewModel
{
    public class MainPageViewModel : INotifyPropertyChanged
    {
        private ObservableCollection<EmployeeHeaderInfo> _employees = new ObservableCollection<EmployeeHeaderInfo>();
        public ObservableCollection<EmployeeHeaderInfo> Employees
        {
            get => _employees;
            set { _employees = value; OnPropertyChanged(); }
        }
        public MainPageViewModel()
        {
            setData();
        }
        private void setData()
        {
            //Static data added in Employees Object
            EmployeeHeaderInfo obj = new EmployeeHeaderInfo();
            obj.Header = "A";
            obj.Add(new EmployeeDetails
            {
                FirstName = "Angelina",
                LastName = "Johnson"
 
            });
            obj.Add(new EmployeeDetails
            {
                FirstName = "Ann",
                LastName = "Williams"
 
            });
            Employees.Add(obj);
 
            obj = new EmployeeHeaderInfo();
            obj.Header = "C";
            obj.Add(new EmployeeDetails
            {
                FirstName = "Cliff",
                LastName = "Jones"
 
            });
            obj.Add(new EmployeeDetails
            {
                FirstName = "Cindy",
                LastName = "Knots"
            });
            Employees.Add(obj);
 
            obj = new EmployeeHeaderInfo();
            obj.Header = "E";
            obj.Add(new EmployeeDetails
            {
                FirstName = "Erica",
                LastName = "Allen"
            });
            obj.Add(new EmployeeDetails
            {
                FirstName = "Emily",
                LastName = "Kelvin"
            });
            Employees.Add(obj);
 
            obj = new EmployeeHeaderInfo();
            obj.Header = "G";
            obj.Add(new EmployeeDetails
            {
                FirstName = "Gleen",
                LastName = "Menard"
            });
            Employees.Add(obj);
 
            obj = new EmployeeHeaderInfo();
            obj.Header = "I";
            obj.Add(new EmployeeDetails
            {
                FirstName = "Ira",
                LastName = "Sawyer"
            });
            Employees.Add(obj);
 
 
            obj = new EmployeeHeaderInfo();
            obj.Header = "J";
            obj.Add(new EmployeeDetails
            {
                FirstName = "Jennifer",
                LastName = "Tyler"
            });
            obj.Add(new EmployeeDetails
            {
                FirstName = "John",
                LastName = "Webber"
            });
            obj.Add(new EmployeeDetails
            {
                FirstName = "Jane",
                LastName = "White"
            });
            obj.Add(new EmployeeDetails
            {
                FirstName = "Johny",
                LastName = "Michael"
            });
            obj.Add(new EmployeeDetails
            {
                FirstName = "John",
                LastName = "Allister"
            });
            Employees.Add(obj);
 
            obj = new EmployeeHeaderInfo();
            obj.Header = "M";
            obj.Add(new EmployeeDetails
            {
                FirstName = "Melvin",
                LastName = "Forbis"
            });
            obj.Add(new EmployeeDetails
            {
                FirstName = "Margaret",
                LastName = "Adelman"
            });
            obj.Add(new EmployeeDetails
            {
                FirstName = "Marie",
                LastName = "Broadbet"
            });
            Employees.Add(obj);
 
            obj = new EmployeeHeaderInfo();
            obj.Header = "P";
            obj.Add(new EmployeeDetails
            {
                FirstName = "Penny",
                LastName = "Diaz"
            });
            obj.Add(new EmployeeDetails
            {
                FirstName = "Paul",
                LastName = "Walker"
            });
            obj.Add(new EmployeeDetails
            {
                FirstName = "Pete",
                LastName = "Packett"
            });
            Employees.Add(obj);
 
            obj = new EmployeeHeaderInfo();
            obj.Header = "R";
            obj.Add(new EmployeeDetails
            {
                FirstName = "Rick",
                LastName = "Novak"
            });
            obj.Add(new EmployeeDetails
            {
                FirstName = "Roger",
                LastName = "Lum"
            });
            obj.Add(new EmployeeDetails
            {
                FirstName = "Ronald",
                LastName = "Barr"
            });
            Employees.Add(obj);
 
 
            obj = new EmployeeHeaderInfo();
            obj.Header = "Z";
            obj.Add(new EmployeeDetails
            {
                FirstName = "Zarin",
                LastName = "Khan"
            });
            Employees.Add(obj);
        }
 
        //OnPropertyChange Event handling
        public event PropertyChangedEventHandler PropertyChanged;
 
        protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

2 comments:

  1. I've been stuck on this problem for a number of days. Spent hours googling until I come across this post. Just want to say thank you. I didn't realise I could do BindableLayout.ItemsSource="{Binding .}" in the nested collection to get the currently being processed item.

    ReplyDelete

Popular Posts