Skip to content

Learn Mobile Development

Alamgeer's Blog

Menu
  • Home
  • Privacy Policy
Menu
StateContainer In MAUI

How to use StateContainer in MAUI

Posted on December 11, 2022January 18, 2023 by Learn Mobile Development

The Xamarin.CommunityToolkit StateContainer in MAUI is a layout which displaying a specific view when your app is in a specific state. StateContainer is an attached properties which enables the user to turn any layout into a state-aware layout. In this article, I’m going to show you how to use StateContainer in MAUI Community Toolkit.

In this sample demo i will take three different custom states like ‘Loading‘, ‘Empty‘ and ‘Success‘

Loading : Will show before loading users.
Empty : Will show when user not available.
Success : Will show when user available.

Let’s Start

In this sample demo we will use CommunityToolkit.Maui nuget package.

CommunityToolkit.Maui

CommunityToolkit.Maui is a collection of Converters, Behaviours, Animations, Custom Views, Effects, Helpers etc. It simplifies the developers task when building Android, iOS, macOS and WinUI applications using MAUI.

1 – Install CommunityToolkit.Maui nuget package

Expander in MAUI

2 – In order to use the .NET MAUI Community Toolkit you need to call the extension method in your MauiProgram.cs file as follows:

using CommunityToolkit.Maui;
using Microsoft.Extensions.Logging;

namespace MAUIStateContainerLayoutSample;

public static class MauiProgram
{
    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();
        builder
            .UseMauiApp<App>()
            .UseMauiCommunityToolkit()
            .ConfigureFonts(fonts =>
            {
                fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
                fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
            });

#if DEBUG
        builder.Logging.AddDebug();
#endif

        return builder.Build();
    }
}

3 – Setting up the UI

3.1 – Create a MainPage.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
    x:Class="MAUIStateContainerLayoutSample.MainPage"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
    x:Name="MainPageContainer">

    <ScrollView>
        <StackLayout Padding="20" Spacing="10">

            <Image
                HeightRequest="150"
                HorizontalOptions="Center"
                SemanticProperties.Description="Cute dot net bot waving hi to you!"
                Source="dotnet_bot.png">

                <Image.Behaviors>
                    <toolkit:IconTintColorBehavior TintColor="Red" />
                </Image.Behaviors>
            </Image>

            <VerticalStackLayout
                toolkit:StateContainer.CurrentState="{Binding CurrentState}"
                toolkit:StateContainer.ShouldAnimateOnStateChange="True"
                Spacing="25"
                VerticalOptions="CenterAndExpand">

                <toolkit:StateContainer.StateViews>

                    <!--  Loading State  -->
                    <VerticalStackLayout toolkit:StateView.StateKey="Loading">
                        <ActivityIndicator
                            HeightRequest="25"
                            HorizontalOptions="CenterAndExpand"
                            IsRunning="True"
                            VerticalOptions="CenterAndExpand"
                            WidthRequest="25"
                            Color="Red" />

                        <Label
                            HorizontalOptions="CenterAndExpand"
                            HorizontalTextAlignment="Center"
                            Text="Loading ..." />
                    </VerticalStackLayout>

                    <!--  Empty State  -->
                    <VerticalStackLayout toolkit:StateView.StateKey="Empty">

                        <Image
                            HeightRequest="200"
                            HorizontalOptions="Center"
                            Source="empty.png" />

                    </VerticalStackLayout>

                    <!--  Success State  -->
                    <StackLayout
                        toolkit:StateView.StateKey="Success"
                        BindableLayout.ItemsSource="{Binding UserList}"
                        HorizontalOptions="FillAndExpand"
                        VerticalOptions="FillAndExpand">
                        <BindableLayout.ItemTemplate>
                            <DataTemplate>
                                <Frame Padding="5" CornerRadius="0">
                                    <StackLayout
                                        Padding="10"
                                        HorizontalOptions="FillAndExpand"
                                        Orientation="Horizontal"
                                        VerticalOptions="FillAndExpand">
                                        <Label
                                            x:Name="UserName"
                                            HorizontalOptions="FillAndExpand"
                                            Text="{Binding .}"
                                            TextColor="Black" />
                                        <Frame
                                            Padding="7"
                                            CornerRadius="15"
                                            HeightRequest="30"
                                            HorizontalOptions="EndAndExpand"
                                            WidthRequest="30">
                                            <Image Source="delete.png" />
                                            <Frame.GestureRecognizers>
                                                <TapGestureRecognizer Command="{Binding BindingContext.DeleteUserCommand, Source={x:Reference MainPageContainer}}" CommandParameter="{Binding .}" />
                                            </Frame.GestureRecognizers>
                                        </Frame>
                                    </StackLayout>
                                </Frame>
                            </DataTemplate>
                        </BindableLayout.ItemTemplate>
                    </StackLayout>

                </toolkit:StateContainer.StateViews>
            </VerticalStackLayout>

            <Entry
                Placeholder="Type name"
                Text="{Binding User}"
                VerticalOptions="EndAndExpand" />

            <Button
                Margin="0,10,0,0"
                Command="{Binding AddUserCommand}"
                HorizontalOptions="CenterAndExpand"
                Text="Add User" />

        </StackLayout>

    </ScrollView>

</ContentPage>
  • As in the above MainPage.xaml i have used three different views for Loading state, Empty state and Success state and each view uniquely identified by StateKey.
  • CurrentState property determines which view with the corresponding StateKey should be displayed. CurrentState is binded with CurrentState string property in MainPageViewModel.cs so that state can be changed at runtime.
  • ShouldAnimateOnStateChange property is used for enabling fade out/in animation while switching between states.

4 – Setting up the ViewModel

4.1 – Create a MainPageViewModel.cs class

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;

namespace MAUIStateContainerLayoutSample
{
    public class MainPageViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public ICommand AddUserCommand { get; set; }
        public ICommand DeleteUserCommand { get; set; }

        private ObservableCollection<string> _list;
        public ObservableCollection<string> UserList
        {
            get => _list;
            set
            {
                _list = value;
                OnPropertyChanged();
            }
        }

        private string _state = "Loading";
        public string CurrentState
        {
            get => _state;
            set
            {
                _state = value;
                OnPropertyChanged();
            }
        }

        private string _user;
        public string User
        {
            get => _user;
            set
            {
                _user = value;
                OnPropertyChanged();
            }
        }

        public MainPageViewModel()
        {
            AddUserCommand = new Command(() =>
            {
                Application.Current.Dispatcher.Dispatch(() =>
                {
                    if (!string.IsNullOrEmpty(User))
                    {
                        UserList.Add(User);

                        if (UserList.Count > 0)
                        {
                            CurrentState = "Success";
                        }

                        User = string.Empty;
                    }
                });
            });

            DeleteUserCommand = new Command<string>((user) =>
            {
                Application.Current.Dispatcher.Dispatch(() =>
                {
                    if (!string.IsNullOrEmpty(user))
                    {
                        UserList.Remove(user);

                        if (UserList.Count <= 0)
                        {
                            CurrentState = "Empty";
                        }
                    }
                });
            });

            // Load list after 5 Second
            Task.Delay(5000).ContinueWith(t => GetList());
        }

        private void GetList()
        {
            UserList = new ObservableCollection<string>()
            {
                "User 1",
                "User 2",
                "User 3",
                "User 4",
            };

            // Change current state from "Loading" to "Success"
            CurrentState = "Success";
        }

        private void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

Now, We have completed the coding, Let’s try to run the application.

5 – Result

That’s all for now!

You can check the full source code here.

Happy Coding! 😀

You may also like

Collectionview as a GridItemLayout

How to use CollectionView as a GridItemLayout in Xamarin Forms

Rotate views on orientation change

How to rotate views on orientation change in Xamarin Forms

Post Views: 769
Share article with

8 thoughts on “How to use StateContainer in MAUI”

  1. Johan Tempelman says:
    December 12, 2022 at 3:35 PM

    Hi, The link to the source code is broken.

    Reply
    1. Alamgeer Ashraf says:
      December 13, 2022 at 1:53 PM

      Hey Johan Tempelman, Thanks for your comment. Now link to source code is available. Please check

      Reply
  2. Navin Prasad says:
    December 13, 2022 at 3:19 AM

    Nice writeup

    Reply
    1. Alamgeer Ashraf says:
      December 13, 2022 at 1:54 PM

      Thanks Navin Prasad

      Reply
  3. Rizvan says:
    December 13, 2022 at 10:37 AM

    Hi, please make tutorial on G pay integration in MAUI

    Reply
  4. StavkiTarve says:
    October 7, 2024 at 7:24 PM

    interesting post
    _________________
    слоты в 1xbet приложение

    Reply
  5. SmiSew says:
    October 10, 2024 at 3:39 AM

    Thanks for the post
    _________________
    pin up casino бест

    Reply
  6. Randyperly says:
    October 18, 2024 at 4:35 AM

    very good
    _________________
    netgame casino бездепозитный бонус

    Reply

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

I'm Alamgeer Ashraf and having 9+ years of experience in enterprises mobile application development with Xamarin Native, Xamarin Forms & .Net MAUI.

Archives

  • February 2023 (1)
  • January 2023 (9)
  • December 2022 (5)
  • November 2022 (6)

Latest Posts

  • Prevent Dark Mode in Xamarin forms
    How to Prevent Dark Mode in Xamarin formsFebruary 3, 2023
  • apply color to Images
    How to apply color to Images and Icons in MAUIJanuary 30, 2023
  • iOS Large Page Title
    How to set iOS large page title in MAUIJanuary 26, 2023
  • Change StatusBar Color
    How to change StatusBar color in MAUIJanuary 22, 2023
  • Item reordering to CollectionView
    How to apply item reordering to CollectionView GridItemsLayout in MAUIJanuary 18, 2023

Popular Posts

  • How to apply color to Images and Icons in MAUI
  • How to use DockLayout in MAUI
  • How to use Expander in MAUI

Latest Comments

  1. Randyperly on How to use StateContainer in MAUIOctober 18, 2024

    very good _________________ netgame casino бездепозитный бонус

  2. SmiSew on How to use StateContainer in MAUIOctober 10, 2024

    Thanks for the post _________________ pin up casino бест

  3. StavkiTarve on How to use StateContainer in MAUIOctober 7, 2024

    interesting post _________________ слоты в 1xbet приложение

  4. Luke on How to use drag and drop gesture to CollectionView in MAUISeptember 25, 2024

    Thanks very much!

  5. Tony - Nhan Nguyen Lhoa Minh on How to apply item reordering to CollectionView GridItemsLayout in MAUIMarch 28, 2024

    That would be an amazing solution. It's easy to comprehend. Thank you very much.

Our Visitor

0 0 7 9 1 7
Users Today : 0
Users Yesterday : 1
Users Last 7 days : 21
Users Last 30 days : 119
Users This Month : 1
Total views : 14159
How to change StatusBar color in MAUI
Trending
How to change StatusBar color in MAUI

Category

  • .Net MAUI
  • MAUI Community Toolkit
  • MVVM
  • Xamarin Community Toolkit
  • Xamarin Forms

Contact Me

  • LinkedIn
      © 2025 Learn Mobile Development