Sdílet prostřednictvím


StateContainer

Zobrazení konkrétního zobrazení, když je vaše aplikace v určitém stavu, je běžným vzorem v libovolné mobilní aplikaci. Příklady se liší od vytváření zobrazení pro načítání až po překryvné zobrazení na obrazovce nebo v pododdílu obrazovky. Prázdná zobrazení stavu se dají vytvořit, pokud se nezobrazují žádná data, a zobrazení stavu chyb se dají zobrazit, když dojde k chybě.

Začínáme

Připojené StateContainer vlastnosti umožňují uživateli převést jakýkoli prvek rozložení, jako je VerticalStackLayout, HorizontalStackLayoutnebo Grid do rozložení s podporou stavu. Každé rozložení s podporou stavu obsahuje kolekci odvozených prvků Zobrazení. Tyto prvky lze použít jako šablony pro různé stavy definované uživatelem. CurrentState Kdykoli je vlastnost řetězce nastavena na hodnotu, která odpovídá StateKey vlastnosti jednoho z prvků Zobrazení, jeho obsah se zobrazí místo hlavního obsahu. Pokud CurrentState je nastaven na null nebo prázdný řetězec, zobrazí se hlavní obsah.

Poznámka:

Při použití StateContainer se všemi Griddefinovanými stavy uvnitř se automaticky zasahují do každého řádku a sloupce Grid.

Syntaxe

StateContainer vlastnosti lze použít v jazyce XAML nebo C#.

XAML

Zahrnutí oboru názvů XAML

Pokud chcete použít sadu nástrojů v XAML, musíte do stránky nebo zobrazení přidat následující xmlns položky:

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

Proto platí následující:

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

Bylo by změněno tak, aby zahrnovalo xmlns následující:

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

Použití StateContaineru

Níže je příklad uživatelského rozhraní vytvořeného pomocí XAML. Toto ukázkové uživatelské rozhraní je připojeno k následujícímu modelu ViewModel, 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>

Revize jazyka C#

Níže je stejné uživatelské rozhraní jako XAML výše vytvořené pomocí značek jazyka C#.

Toto ukázkové uživatelské rozhraní je připojeno k následujícímu modelu ViewModel, 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);
}

ViewModel

Při použití ICommand změny (např. při použití Button.Command ke změně stavů) doporučujeme použít funkci CanStateBeChangedICommand.CanExecute().CurrentState

Níže je příklad MVVM s využitím komunitní sady nástrojů 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;
    }
}

Ve výchozím nastavení StateContainer změní stav bez animace. Pokud chcete přidat vlastní animaci, můžete použít tuto metodu 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);
    }
}

Jak to funguje v iOSu:

StateContainer Animation

Vlastnosti

StateContainer

StateContainer vlastnosti lze použít pro libovolný Layout zděděný element.

Vlastnost Type Popis
StateViews IList<View> Dostupné View prvky, které se mají použít jako šablony stavů.
Aktuální stav string Určuje, který View prvek s odpovídajícím StateKey prvkem by měl být zobrazen.

Upozornění: Nelze změnit, když probíhá změna stavu. CurrentState
CanStateChange bool CurrentState Kdy truelze vlastnost změnit. Pokud falsenelze změnit, protože se právě mění.

Upozornění: Pokud CurrentState se změní, když CanStateChanged je false, StateContainerException je vyvolán.

StateView

StateView vlastnosti lze použít pro libovolný View zděděný element.

Vlastnost Type Popis
StateKey string Název stavu.

Metody

StateContainer

metoda Argumenty Popis
ChangeStateWithAnimation (statické) BindableObject bindable, řetězec? Stav, Animace? beforeStateChange, Animace? afterStateChange, Token CancellationToken Změna stavu pomocí vlastní animace
ChangeStateWithAnimation (statické) BindableObject bindable, řetězec? state, Func<VisualElement, CancellationToken, Task>? beforeStateChange, Func<VisualElement, CancellationToken, Task>? afterStateChange, CancellationToken cancellationToken Změna stavu pomocí vlastní animace
ChangeStateWithAnimation (statické) BindableObject bindable, řetězec? state, CancellationToken token Změňte stav pomocí výchozí animace prolnutí.

Příklady

Příklad této funkce najdete v ukázkové aplikaci .NET MAUI Community Toolkit.

rozhraní API

Zdrojový kód StateContainer najdete v úložišti .NET MAUI Community Toolkit na GitHubu.