Udostępnij za pośrednictwem


StateContainer

Wyświetlanie określonego widoku, gdy aplikacja jest w określonym stanie, jest typowym wzorcem w każdej aplikacji mobilnej. Przykłady obejmują tworzenie widoków ładowania do nakładki na ekranie lub podsekcję ekranu. Puste widoki stanu można utworzyć, gdy nie ma danych do wyświetlenia, a widoki stanu błędu mogą być wyświetlane po wystąpieniu błędu.

Wprowadzenie

Dołączone StateContainer właściwości umożliwiają użytkownikowi przekształcenie dowolnego elementu układu, takiego jak VerticalStackLayout, HorizontalStackLayoutlub Grid w układ obsługujący stan. Każdy układ obsługujący stan zawiera kolekcję elementów pochodnych Widoku. Te elementy mogą być używane jako szablony dla różnych stanów zdefiniowanych przez użytkownika. CurrentState Za każdym razem, gdy właściwość string jest ustawiona na wartość zgodną StateKey z właściwością jednego z elementów Widoku, jego zawartość będzie wyświetlana zamiast zawartości głównej. Gdy CurrentState jest ustawiona wartość null lub pusty ciąg, zostanie wyświetlona główna zawartość.

Uwaga

W przypadku używania z StateContainer elementem Gridwszystkie zdefiniowane stany wewnątrz obiektu będą automatycznie obejmować każdy wiersz i kolumnę obiektu Grid.

Składnia

StateContainer właściwości można używać w języku XAML lub C#.

XAML

Dołączanie przestrzeni nazw XAML

Aby można było używać zestawu narzędzi w języku XAML, należy dodać następujące xmlns elementy do strony lub widoku:

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

W związku z tym następujące elementy:

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

Zostanie zmodyfikowana tak, aby zawierała następujące xmlns elementy:

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

Korzystanie z elementu StateContainer

Poniżej przedstawiono przykładowy interfejs użytkownika utworzony przy użyciu języka XAML. Ten przykładowy interfejs użytkownika jest połączony z poniższym modelem 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>

Znaczniki języka C#

Poniżej znajduje się ten sam interfejs użytkownika co powyższy kod XAML utworzony przy użyciu znaczników języka C#.

Ten przykładowy interfejs użytkownika jest połączony z poniższym modelem 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

W przypadku używania elementu do zmiany (np. w przypadku używania Button.Command funkcji do zmiany stanów) zalecamy użycie polecenia dla elementu CanStateBeChangedICommand.CanExecute().CurrentStateICommand

Poniżej znajduje się przykład MVVM korzystający z zestawu narzędzi 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;
    }
}

Domyślnie StateContainer zmienia stan bez animacji. Aby dodać animację niestandardową, możesz użyć ChangeStateWithAnimation metody :

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);
    }
}

W ten sposób działa w systemie iOS:

StateContainer Animation

Właściwości

StateContainer

Właściwości StateContainer mogą być używane w dowolnym Layout dziedziczącym elemenie.

Właściwość Type Opis
StateViews IList<View> Dostępne View elementy, które mają być używane jako szablony stanów.
CurrentState string Określa, który View element z odpowiednim elementem StateKey powinien być wyświetlany.

Ostrzeżenie: CurrentState nie można zmienić, gdy zmiana stanu jest w toku
CanStateChange bool CurrentState Gdy truewłaściwość można zmienić. Nie falsemożna zmienić elementu , ponieważ jest on obecnie zmieniany.

Ostrzeżenie: jeśli CurrentState parametr zostanie zmieniony, gdy CanStateChanged parametr ma falsewartość , jest StateContainerException zgłaszany.

Widok stanu

Właściwości StateView można używać w dowolnym View dziedziczącym elemecie.

Właściwość Type Opis
StateKey string Nazwa stanu.

Metody

StateContainer

Method Argumenty opis
ChangeStateWithAnimation (statyczna) BindableObject bindable, string? stan, animacja? beforeStateChange, Animacja? afterStateChange, token CancellationToken Zmień stan za pomocą animacji niestandardowej.
ChangeStateWithAnimation (statyczna) BindableObject bindable, string? state, Func<VisualElement, CancellationToken, Task>? beforeStateChange, Func<VisualElement, CancellationToken, Task>? afterStateChange, CancellationToken cancellationToken Zmień stan za pomocą animacji niestandardowej.
ChangeStateWithAnimation (statyczna) BindableObject bindable, string? state, CancellationToken token Zmień stan przy użyciu domyślnej animacji zanikania.

Przykłady

Przykład tej funkcji można znaleźć w aplikacji przykładowej zestawu narzędzi .NET MAUI Community Toolkit.

interfejs API

Kod źródłowy można StateContainer znaleźć w repozytorium GitHub zestawu narzędzi .NET MAUI Community Toolkit.