Partager via


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. Des 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.

Mise en route

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

Remarque

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 colonne du Grid.

Syntaxe

Les propriétés StateContainer 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"

Il en résulte 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#

Voici la même interface utilisateur que le code XAML, ci-dessus, créée à l’aide de 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.CanStateChange,
    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);
}

Vue modèle

Lorsque vous utilisez un ICommand pour modifier CurrentState (par exemple, lorsque vous utilisez Button.Command pour modifier les états), nous vous recommandons d’utiliser CanStateBeChanged à la place de ICommand.CanExecute().

Voici un exemple MVVM utilisant le kit de ressources communauté MVVM :

[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 d’état sans animation. Pour ajouter une animation personnalisée, vous pouvez utiliser la méthode ChangeStateWithAnimation :

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 de StateContainer peuvent être utilisées sur n’importe quel élément héritant Layout.

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

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

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

StateView

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

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 Modifiez l’état avec une animation personnalisée.
ChangeStateWithAnimation (statique) BindableObject bindable, string? state, Func<VisualElement, CancellationToken, Task>? beforeStateChange, Func<VisualElement, CancellationToken, Task>? afterStateChange, CancellationToken cancellationToken Modifiez l’état avec une animation personnalisée.
ChangeStateWithAnimation (statique) BindableObject bindable, string? state, CancellationToken token Modifiez l’état à l’aide de l’animation de fondu par défaut.

Exemples

Vous trouverez un exemple d’utilisation de cette fonctionnalité dans l’exemple d’application du kit d’outils de la communauté .NET MAUI.

API

Vous pouvez trouver le code source deStateContainer sur le référentiel du kit de ressources de la communauté .NET MAUI sur GitHub.