アプリが特定の状態のときに特定のビューを表示することは、あらゆるモバイル アプリに共通するパターンです。 たとえば、画面上、または画面の一部分にオーバーレイする読み込みビューの作成などがあります。 空の状態ビューは、表示するデータがない場合に作成でき、エラー状態ビューは、エラーが発生した場合に表示できます。
はじめに
StateContainer に付属するプロパティを使用すると、ユーザーは VerticalStackLayout、HorizontalStackLayout、Grid のようなレイアウト要素を状態認識レイアウトに変換できます。 各状態認識レイアウトには、ビュー派生要素のコレクションが含まれています。 これらの要素は、ユーザーによって定義されたさまざまな状態のテンプレートとして使用できます。 CurrentState 文字列プロパティに、ビュー要素の StateKey プロパティと一致する値が設定されると、メイン コンテンツではなく、その内容が表示されます。 CurrentState が null または空文字列に設定されると、メイン コンテンツが表示されます。
Note
StateContainer を Grid で使用する場合、その内部で定義された状態は、自動的に 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
StateContainer プロパティは、任意の Layout 継承要素で使用できます。
| プロパティ | タイプ | 説明 |
|---|---|---|
| StateViews | IList<View> |
状態テンプレートとして使用可能な View 要素。 |
| CurrentState | string |
どの View 要素に対応する StateKey を表示する必要があるかを決定します。 警告: 状態変更中は CurrentState を変更できません |
| CanStateChange | bool |
true の場合、CurrentState プロパティを変更できます。 false の場合は、現在変更中のため変更できません。 警告: CanStateChanged が false のときに 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 リポジトリにあります。
.NET MAUI Community Toolkit