StateContainer

アプリが特定の状態のときに特定のビューを表示することは、モバイル アプリ全体で一般的なパターンです。 たとえば、読み込みビューを作成することから、それを画面全体または画面の一部分にオーバーレイ表示することまで、さまざまな例があります。 表示するデータがない場合は空の状態ビューを作成でき、エラーが発生したときにエラー状態ビューを表示できます。

はじめに

StateContainer添付プロパティを使用すると、ユーザーはVerticalStackLayoutHorizontalStackLayoutGridなどのレイアウト要素を状態対応のレイアウトに変換できます。 各状態対応レイアウトには、View 派生要素のコレクションが含まれています。 これらの要素は、ユーザーによって定義されたさまざまな状態のテンプレートとして使用できます。 CurrentState文字列プロパティが、いずれかの View 要素のStateKey プロパティと一致する値に設定されると、その内容はメイン コンテンツではなく表示されます。 CurrentStatenullまたは空の文字列に設定すると、メイン コンテンツが表示されます。

Note

StateContainerGridを使用すると、その中の定義された状態は、Gridのすべての行と列に自動的にまたがります。

Syntax

StateContainer プロパティは XAML または C# で使用できます。

XAML

XAML 名前空間を含める

XAML でこのツールキットを使用するには、次の xmlns をページまたはビューに追加する必要があります。

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

したがって、以下の通りです

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

次のように、xmlns を含むように変更されます。

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

StateContainer の使用

XAML を使用して作成された UI の例を次に示します。 このサンプル UI は、以下の 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>

C# マークアップ

C # マークアップを使用して作成された XAML と同じ UI を次に示します。

このサンプル UI は、以下の 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.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);
}

ビューモデル

ICommandを使用してCurrentStateを変更する場合 (たとえば、Button.Commandを使用して状態を変更する場合)、CanStateBeChangedICommand.CanExecute()を使用することをお勧めします。

MVVM Community Toolkit を使用した 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;
    }
}

既定では、 StateContainer はアニメーションなしで状態を変更します。 カスタム アニメーションを追加するには、 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);
    }
}

iOS での動作は次のとおりです。

StateContainer アニメーション

プロパティ

StateContainer

StateContainer プロパティは、継承する任意の Layout 要素で使用できます。

財産 タイプ Description
StateViews IList<View> 状態テンプレートとして使用できる View 要素。
現在の状態 string 対応するViewを持つどのStateKey要素を表示するかを決定します。

警告: 状態変更の進行中は、 CurrentState を変更できません
CanStateChange bool trueすると、CurrentState プロパティを変更できます。 false、現在変更中のため、変更できません。

警告: CanStateChangedfalse のときに CurrentState が変更されると、StateContainerException がスローされます。

StateView

StateView プロパティは、継承する任意の View 要素で使用できます。

財産 タイプ Description
StateKey string 状態の名前。

Methods

StateContainer

メソッド Arguments Description
ChangeStateWithAnimation (static) BindableObject バインド可能、文字列?状態、アニメーション?beforeStateChange,Animation?afterStateChange、CancellationToken トークン カスタム アニメーションを使用して状態を変更します。
ChangeStateWithAnimation (static) BindableObject バインド可能、文字列?state、Func<VisualElement、CancellationToken、Task>? beforeStateChange、Func<VisualElement、CancellationToken、Task>? afterStateChange、CancellationToken cancellationToken カスタム アニメーションを使用して状態を変更します。
ChangeStateWithAnimation (static) BindableObject バインド可能、文字列?state、CancellationToken トークン 既定のフェード アニメーションを使用して状態を変更します。

例示

この機能の例は、.NET MAUI Community Toolkit サンプル アプリケーションで動作しています。

API

StateContainer のソース コードは、.NET MAUI Community Toolkit GitHub リポジトリで確認できます。