Articles in this section
Category / Section

How to bind ItemSource using Reactive MVVM in Xamarin.Forms Accordion (SfAccordion)

2 mins read

The SfAccordion allows you to bind ItemSource to the reactive UI ViewModel which is a composable and cross-platform model-view-viewmodel framework for all .NET platforms.

To achieve this, follow the below steps:

STEP 1: Install the ReactiveUI and ReactiveUI.XamForms in your project.

STEP 2: Create ViewModel which should implement ReactiveObject.

public class ViewModel : ReactiveObject
{
    private ObservableCollection<ContactInfo> contacts;
    #region Properties
    public ObservableCollection<ContactInfo> Contacts
    {
        get
        {
            return this.contacts;
        }
 
        set
        {
            this.RaiseAndSetIfChanged(ref contacts, value);
        }
    }
    public Command<object> TapCommand { get; set; }
 
    #endregion
 
    #region Constructor
 
    public ViewModel()
    {
        Contacts = new ObservableCollection<ContactInfo>();
        TapCommand = new Command<object>(OnTapped);
        Contacts.Add(new ContactInfo() { Type = "A", Contacts = new ObservableCollection<Contact>() { new Contact() { ContactName = "Adam" }, new Contact { ContactName = "Aaron" } } });
        Contacts.Add(new ContactInfo() { Type = "B", Contacts = new ObservableCollection<Contact>() { new Contact() { ContactName = "Bolt" }, new Contact { ContactName = "Bush" } } });
        Contacts.Add(new ContactInfo() { Type = "C", Contacts = new ObservableCollection<Contact>() { new Contact() { ContactName = "Clark" }, new Contact { ContactName = "Clara" } } });
    }
 
    #endregion
 
    #region Private Methods
 
    private void OnTapped(object obj)
    {
 
        var data = obj as Contact;
        App.Current.MainPage.DisplayAlert("Message", "Tapped Accoridon item is : " + data.ContactName, "Ok");
    }
    #endregion
}

STEP 3: ContentPage should inherit from ReactiveContentPage<TViewModel> and we are going to use ReactiveUI Binding to bind our ViewModel to our View.

XMAL

public partial class MainPage : ReactiveContentPage<ViewModel>
{
        public MainPage(ViewModel viewModel)
        {
            
        }
}

C#

<?xml version="1.0" encoding="utf-8" ?>
<rxui:ReactiveContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:AccordionXamarin"
             xmlns:rxui="clr-namespace:ReactiveUI.XamForms;assembly=ReactiveUI.XamForms"
             xmlns:syncfusion="clr-namespace:Syncfusion.XForms.Accordion;assembly=Syncfusion.Expander.XForms"
             xmlns:sflistview="clr-namespace:Syncfusion.ListView.XForms;assembly=Syncfusion.SfListView.XForms"
             x:Class="AccordionXamarin.MainPage"
             x:TypeArguments="local:ViewModel" >
    <ContentPage.Content>
        <StackLayout>
            <syncfusion:SfAccordion x:Name="Accordion" BindableLayout.ItemsSource="{Binding Contacts}" ExpandMode="SingleOrNone" >
                <BindableLayout.ItemTemplate>
                    <DataTemplate>
                        <syncfusion:AccordionItem  >
                            <syncfusion:AccordionItem.Header >
                                <Grid HeightRequest="60">
                                    <Label Text="{Binding Type}" BackgroundColor="Aqua" VerticalTextAlignment="Center" HorizontalTextAlignment="Center"/>
                                </Grid>
                            </syncfusion:AccordionItem.Header>
                            <syncfusion:AccordionItem.Content>
                                <Grid x:Name="mainGrid" Padding="4" HeightRequest="135" >
                                    <sflistview:SfListView AllowGroupExpandCollapse="True" IsScrollingEnabled="False" x:Name="listView" IsScrollBarVisible="False" AutoFitMode="DynamicHeight"
                                    ItemSpacing="3" ItemsSource="{Binding Contacts}" >
                                        <sflistview:SfListView.ItemTemplate>
                                            <DataTemplate>
                                                <Grid HeightRequest="60" Padding="1" >
                                                    <Label Text="{Binding ContactName}" BackgroundColor="LightBlue"/>
                                                    <Grid.GestureRecognizers>
                                                        <TapGestureRecognizer Command="{Binding Path=BindingContext.TapCommand, Source={x:Reference Accordion}}" CommandParameter="{Binding .}" />
                                                    </Grid.GestureRecognizers>
                                                </Grid>
                                            </DataTemplate>
                                        </sflistview:SfListView.ItemTemplate>
                                    </sflistview:SfListView>
                                </Grid>
                            </syncfusion:AccordionItem.Content>
                        </syncfusion:AccordionItem>
                    </DataTemplate>
                </BindableLayout.ItemTemplate>
            </syncfusion:SfAccordion>
        </StackLayout>
    </ContentPage.Content>
</rxui:ReactiveContentPage>

STEP 4: View can be connected in one-way dependent manner to the ViewModel through bindings. You can set the BindingContext for the SfAccordion in MainPage.cs itself in code behind like below.

public partial class MainPage : ReactiveContentPage<ViewModel>
{
        public MainPage(ViewModel viewModel)
        {
            ViewModel = viewModel;
            InitializeComponent();
        }
}

View Sample in GitHub

A picture containing graphical user interface

Description automatically generated

Did you find this information helpful?
Yes
No
Help us improve this page
Please provide feedback or comments
Comments (0)
Please  to leave a comment
Access denied
Access denied