StateContainer

L’affichage d’une vue spécifique lorsque votre application est dans un état spécifique est un modèle courant dans n’importe quelle application mobile. Les exemples vont de la création de vues de chargement à la superposition sur l’écran ou sur une sous-section de l’écran. Les vues d’état vides peuvent être créées lorsqu’il n’y a pas de données à afficher et que les vues d’état d’erreur peuvent être affichées lorsqu’une erreur se produit.

Getting Started

Les StateContainer propriétés jointes permettent à l’utilisateur de transformer n’importe quel élément de disposition comme un VerticalStackLayout, HorizontalStackLayoutou Grid en disposition prenant en compte l’état. Chaque mise en page sensible à l’état contient un ensemble d’éléments dérivés de View. Ces éléments peuvent être utilisés comme modèles pour différents états définis par l’utilisateur. Chaque fois que la CurrentState propriété de chaîne est définie sur une valeur qui correspond à la StateKey propriété d’un des éléments View, son contenu s’affiche au lieu du contenu principal. Lorsque CurrentState est défini sur null ou sur une chaîne vide, le contenu principal s’affiche.

Note

Lorsque vous utilisez StateContainer avec un Grid, tous les états définis à l’intérieur de celui-ci s’étendent automatiquement sur chaque ligne et chaque colonne du Grid.

Syntax

StateContainer les propriétés peuvent être utilisées en XAML ou en C#.

XAML

Y compris l’espace de noms XAML

Pour utiliser le kit de ressources dans XAML, le xmlns suivant doit être ajouté à votre page ou à votre affichage :

xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"

Par conséquent, ce qui suit :

<ContentPage
    x:Class="CommunityToolkit.Maui.Sample.Pages.MyPage"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">

</ContentPage>

Serait modifié pour inclure le xmlns de la manière suivante :

<ContentPage
    x:Class="CommunityToolkit.Maui.Sample.Pages.MyPage"
    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">

</ContentPage>

Utilisation de StateContainer

Vous trouverez ci-dessous un exemple d’interface utilisateur créé à l’aide de XAML. Cet exemple d’interface utilisateur est connecté au ViewModel ci-dessous. StateContainerViewModel

<ContentPage 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:Class="MyProject.MyStatePage"
             BindingContext="StateContainerViewModel">

    <VerticalStackLayout 
        toolkit:StateContainer.CurrentState="{Binding CurrentState}"
        toolkit:StateContainer.CanStateChange="{Binding CanStateChange}">

        <toolkit:StateContainer.StateViews>
            <VerticalStackLayout toolkit:StateView.StateKey="Loading">
                <ActivityIndicator IsRunning="True" />
                <Label Text="Loading Content..." />
            </VerticalStackLayout>
            <Label toolkit:StateView.StateKey="Success" Text="Success!" />
        </toolkit:StateContainer.StateViews>

        <Label Text="Default Content" />
        <Button Text="Change State" Command="{Binding ChangeStateCommand}" />

    </VerticalStackLayout>

</ContentPage>

Balisage C#

Vous trouverez ci-dessous la même interface utilisateur que le code XAML, ci-dessus, créé à l’aide du balisage C#.

Cet exemple d’interface utilisateur est connecté au ViewModel ci-dessous. StateContainerViewModel

using CommunityToolkit.Maui.Layouts;
using CommunityToolkit.Maui.Markup;

BindingContext = new StateContainerViewModel();

Content = new VerticalStackLayout()
{
    new Label()
        .Text("Default Content"),
    
    new Button()
        .Text("Change State")
        .Bind(
            Button.CommandProperty,
            static (StateContainerViewModel vm) => vm.ChangeStateCommand,
            mode: BindingMode.OneTime)
}.Bind(
    StateContainer.CurrentStateProperty,
    static (StateContainerViewModel vm) => vm.CurrentState,
    static (StateContainerViewModel vm, string currentState) => vm.CurrentState = currentState)
 .Bind(
    StateContainer.CanStateChangeProperty,
    static (StateContainerViewModel vm) => vm.CanStateChange,
    static (StateContainerViewModel vm, bool canStateChange) => vm.CanStateChange = canStateChange)
 .Assign(out VerticalStackLayout layout);

var stateViews = new List<View>()
{
    //States.Loading
    new VerticalStackLayout()
    {
        new ActivityIndicator() { IsRunning = true },
        new Label().Text("Loading Content")
    },

    //States.Success
    new Label().Text("Success!")
};

StateView.SetStateKey(stateViews[0], States.Loading);
StateView.SetStateKey(stateViews[1], States.Success);

StateContainer.SetStateViews(layout, stateViews);

static class States
{
    public const string Loading = nameof(Loading);
    public const string Success = nameof(Success);
}

ViewModel

Lors de l’utilisation d’un ICommand pour modifier CurrentState (par exemple, lors de l’utilisation de Button.Command pour modifier les états), nous avons recommandé d’utiliser CanStateBeChanged pour ICommand.CanExecute().

Voici un exemple MVVM qui utilise le MVVM Community Toolkit :

[INotifyPropertyChanged]
public partial class StateContainerViewModel
{
    [ObservableProperty]
    [NotifyCanExecuteChangedFor(nameof(ChangeStateCommand))]
    bool canStateChange;

    [ObservableProperty]
    string currentState = States.Loading;

    [RelayCommand(CanExecute = nameof(CanStateChange))]
    void ChangeState()
    {
        CurrentState = States.Success;
    }
}

Par défaut StateContainer , change l’état sans animation. Pour ajouter une animation personnalisée, vous pouvez utiliser la ChangeStateWithAnimation méthode :

async Task ChangeStateWithCustomAnimation()
{
    var targetState = "TargetState";
    var currentState = StateContainer.GetCurrentState(MyBindableObject);
    if (currentState == targetState)
    {
        await StateContainer.ChangeStateWithAnimation(
            MyBindableObject,
            null,
            (element, token) => element.ScaleTo(0, 100, Easing.SpringIn).WaitAsync(token),
            (element, token) => element.ScaleTo(1, 250, Easing.SpringOut).WaitAsync(token),
            CancellationToken.None);
    }
    else
    {
        await StateContainer.ChangeStateWithAnimation(
            MyBindableObject,
            targetState,
            (element, token) => element.ScaleTo(0, 100, Easing.SpringIn).WaitAsync(token),
            (element, token) => element.ScaleTo(1, 250, Easing.SpringOut).WaitAsync(token),
            CancellationToken.None);
    }
}

Voici comment cela fonctionne sur iOS :

StateContainer Animation

Propriétés

StateContainer

Les propriétés StateContainer peuvent être utilisées sur n’importe quel Layout élément hérité.

Propriété Type Description
StateViews IList<View> Éléments disponibles View à utiliser comme modèles d’état.
ÉtatActuel string Détermine l’élément View avec le correspondant StateKey qui doit être affiché.

Avertissement : CurrentState ne peut pas être modifié pendant qu’une modification d’état est en cours
CanStateChange bool Quand true, la CurrentState propriété peut être modifiée. false ne peut pas être modifié, car il est actuellement en cours de modification.

Avertissement : si CurrentState est modifié lorsque CanStateChanged vaut false, une StateContainerException est levée.

StateView

Les propriétés StateView peuvent être utilisées sur n’importe quel View élément hérité.

Propriété Type Description
StateKey string Nom de l’état.

Méthodes

StateContainer

Méthode Arguments Description
ChangeStateWithAnimation (statique) BindableObject bindable, string ? état, Animation ? beforeStateChange, Animation ? afterStateChange, token CancellationToken Modifier l’état avec une animation personnalisée.
ChangeStateWithAnimation (statique) BindableObject bindable, string ? state, Func<VisualElement, CancellationToken, Task> ? beforeStateChange, Func<VisualElement, CancellationToken, Task> ? aprèsChangementÉtat, JetonAnnulation jetonAnnulation Modifier l’état avec une animation personnalisée.
ChangeStateWithAnimation (statique) BindableObject bindable, string ? state, CancellationToken token Modifier l’état avec l’animation de fondu par défaut.

Exemples

Vous trouverez un exemple de cette fonctionnalité en action dans l’exemple d’application .NET MAUI Community Toolkit.

API

Vous trouverez le code source de StateContainer sur le dépôt .NET MAUI Community Toolkit GitHub.