Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Mostrar uma vista específica quando a sua aplicação está num estado específico é um padrão comum em qualquer aplicação móvel. Os exemplos vão desde a criação de vistas de carregamento até sobreposições no ecrã, ou numa subseção do ecrã. Podem ser criadas vistas de estado vazias quando não há dados para mostrar, e vistas de estado de erro podem ser exibidas quando ocorre um erro.
Introdução
As propriedades associadas StateContainer permitem ao utilizador transformar qualquer elemento de layout, tal como um VerticalStackLayout, HorizontalStackLayout ou Grid, num layout com reconhecimento de estado. Cada disposição sensível ao estado contém uma coleção de elementos derivados de View. Estes elementos podem ser usados como modelos para diferentes estados definidos pelo utilizador. Sempre que a CurrentState propriedade da cadeia é definida para um valor que corresponde à StateKey propriedade de um dos elementos da View, o seu conteúdo será exibido em vez do conteúdo principal. Quando CurrentState está definida como null ou vazia string, o conteúdo principal é exibido.
Observação
Ao usar StateContainer com um Grid, quaisquer estados definidos dentro dele irão automaticamente abranger todas as linhas e colunas do Grid.
Sintaxe
StateContainer as propriedades podem ser usadas em XAML ou C#.
XAML
Incluindo o namespace XAML
Para usar o kit de ferramentas em XAML, a seguinte xmlns precisa ser adicionada à sua página ou vista.
xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
Por conseguinte, o seguinte:
<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>
Seria modificado para incluir o xmlns da seguinte forma:
<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>
Utilização do StateContainer
Abaixo está um exemplo de interface criada usando XAML. Esta interface de exemplo está ligada ao ViewModel abaixo, 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>
Marcação em C#
Abaixo está a mesma interface do XAML, acima, criada usando Marcação C#.
Esta interface de exemplo está ligada ao ViewModel abaixo, 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);
}
Modelo de Visualização
Ao usar um ICommand para mudar CurrentState (por exemplo, ao usar Button.Command para mudar estados), recomendamos usar CanStateBeChanged para ICommand.CanExecute().
Abaixo está um exemplo de MVVM usando o 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;
}
}
Por defeito, StateContainer muda de estado sem animação. Para adicionar uma animação personalizada, pode usar o ChangeStateWithAnimation método:
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);
}
}
É assim que funciona no iOS:
Propriedades
StateContainer
As propriedades StateContainer podem ser usadas em qualquer Layout elemento herdeiro.
| Propriedade | Tipo | Descrição |
|---|---|---|
| StateViews | IList<View> |
Os elementos View disponíveis para serem utilizados como modelos de estado. |
| Estado Atual | string |
Determina qual View elemento com o correspondente StateKey deve ser exibido. Aviso: CurrentState não pode ser alterado enquanto estiver em curso uma alteração de estado |
| CanStateChange | bool |
Quando true, a propriedade CurrentState pode ser alterada. Se false, não pode ser alterado porque está neste momento a ser alterado. Aviso: Se CurrentState for alterado quando CanStateChanged é false, a StateContainerException é lançada. |
StateView
As propriedades StateView podem ser usadas em qualquer View elemento herdeiro.
| Propriedade | Tipo | Descrição |
|---|---|---|
| StateKey | string |
Nome do estado. |
Methods
StateContainer
| Método | Argumentos | Descrição |
|---|---|---|
| ChangeStateWithAnimation (estática) | BindableObject bindable, string? estado, Animação? antesEstadoMudança, Animação? afterStateChange, token CancellationToken | Muda o estado com animação personalizada. |
| ChangeStateWithAnimation (estática) | BindableObject bindable, string? state, Func<VisualElement, CancellationToken, Task>? beforeStateChange, Func<VisualElement, CancellationToken, Task>? afterStateChange, CancellationToken cancellationToken | Muda o estado com animação personalizada. |
| ChangeStateWithAnimation (estática) | BindableObject bindable, string? state, CancellationToken token | Altere o estado com a animação de esbatimento predefinida. |
Exemplos
Você pode encontrar um exemplo desse recurso em ação no .NET MAUI Community Toolkit Sample Application.
API
Você pode encontrar o código-fonte para StateContainer no repositório GitHub do .NET MAUI Community Toolkit.
.NET MAUI Community Toolkit