次の方法で共有


StateContainer

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

はじめに

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

Note

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

構文

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

以下は、上記の XAML と同じ UI を C# のマークアップを使用して作成したものです。

このサンプル 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);
}

ViewModel

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

以下は、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 Animation

プロパティ

StateContainer

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

プロパティ タイプ 説明
StateViews IList<View> 状態テンプレートとして使用可能な View 要素。
CurrentState string どの View 要素に対応する StateKey を表示する必要があるかを決定します。

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

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

StateView

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

プロパティ タイプ 説明
StateKey string 州の名前。

メソッド

StateContainer

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

この機能の動作例は 「.NET MAUI Community Toolkit サンプル アプリケーション」で確認できます。

API

StateContainer のソース コードは、.NET MAUI Community Toolkit の GitHub リポジトリにあります。