Xamarin.Forms Gatilhos

Baixar exemplo Baixar o exemplo

Os gatilhos permitem expressar ações declarativamente em XAML que alteram a aparência dos controles com base em eventos ou alterações de propriedade. Além disso, os gatilhos de estado, que são um grupo especializado de gatilhos, definem quando um VisualState deve ser aplicado.

Você pode atribuir um gatilho diretamente a um controle ou adicioná-lo a um dicionário de recursos na página ou aplicativo a ser aplicado a vários controles.

Disparadores de propriedade

Um gatilho simples pode ser expresso puramente em XAML, adicionando um elemento Trigger a uma coleção de gatilhos do controle. Este exemplo mostra um gatilho que altera uma cor da tela de fundo Entry quando recebe o foco:

<Entry Placeholder="enter name">
    <Entry.Triggers>
        <Trigger TargetType="Entry"
                 Property="IsFocused" Value="True">
            <Setter Property="BackgroundColor" Value="Yellow" />
            <!-- multiple Setters elements are allowed -->
        </Trigger>
    </Entry.Triggers>
</Entry>

As partes importantes da declaração do gatilho são:

  • TargetType – o tipo de controle ao qual o gatilho se aplica.

  • Propriedade – a propriedade no controle que é monitorado.

  • Valor – o valor, quando ocorre para a propriedade monitorada, que faz com que o gatilho seja ativado.

  • Setter – uma coleção de elementos Setter pode ser adicionada quando a condição do gatilho for atendida. Você deve especificar Property e Value para definir.

  • EnterActions e ExitActions (não mostrado) – são escritos em código e podem ser usados em (ou em vez de) elementos Setter. Eles são descritos abaixo.

Aplicar um gatilho usando um estilo

Gatilhos também podem ser adicionados a uma declaração Style em um controle, em uma página ou um aplicativo ResourceDictionary. Este exemplo declara um estilo implícito (ou seja, não Key está definido), o que significa que ele será aplicado a todos os Entry controles na página.

<ContentPage.Resources>
    <ResourceDictionary>
        <Style TargetType="Entry">
                        <Style.Triggers>
                <Trigger TargetType="Entry"
                         Property="IsFocused" Value="True">
                    <Setter Property="BackgroundColor" Value="Yellow" />
                    <!-- multiple Setters elements are allowed -->
                </Trigger>
            </Style.Triggers>
        </Style>
    </ResourceDictionary>
</ContentPage.Resources>

Gatilhos de dados

Os gatilhos de dados usam a associação de dados para monitorar outro controle para fazer com que Setters sejam chamados. Em vez do atributo Property em um gatilho de propriedade, defina o atributo Binding para monitorar o valor especificado.

O exemplo a seguir usa a sintaxe de associação de dados {Binding Source={x:Reference entry}, Path=Text.Length} que é como nos referimos às propriedades de outro controle. Quando o tamanho do entry for zero, o gatilho será ativado. Neste exemplo, o gatilho desabilita o botão quando a entrada está vazia.

<!-- the x:Name is referenced below in DataTrigger-->
<!-- tip: make sure to set the Text="" (or some other default) -->
<Entry x:Name="entry"
       Text=""
       Placeholder="required field" />

<Button x:Name="button" Text="Save"
        FontSize="Large"
        HorizontalOptions="Center">
    <Button.Triggers>
        <DataTrigger TargetType="Button"
                     Binding="{Binding Source={x:Reference entry},
                                       Path=Text.Length}"
                     Value="0">
            <Setter Property="IsEnabled" Value="False" />
            <!-- multiple Setters elements are allowed -->
        </DataTrigger>
    </Button.Triggers>
</Button>

Dica

Ao avaliar Path=Text.Length sempre, forneça um valor padrão para a propriedade de destino (por exemplo, Text="") porque caso contrário, será null e o gatilho não funcionará como você espera.

Além de Setterespecificar s, você também pode fornecer EnterActions e ExitActions.

Gatilhos de evento

O elemento EventTrigger requer apenas uma propriedade Event, como "Clicked" no exemplo a seguir.

<EventTrigger Event="Clicked">
    <local:NumericValidationTriggerAction />
</EventTrigger>

Observe que não há elementos Setter, mas, em vez disso, uma referência a uma classe definida por local:NumericValidationTriggerAction, que requer que o xmlns:local seja declarado no XAML da página:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:WorkingWithTriggers;assembly=WorkingWithTriggers"

A classe em si implementa TriggerAction, o que significa que ela deve fornecer uma substituição para o método Invoke que é chamado sempre que ocorre o evento de gatilho.

Uma implementação de ação do gatilho deve:

  • Implementar a classe TriggerAction<T> genérica com o parâmetro genérico correspondente com o tipo de controle ao qual o gatilho será aplicado. É possível usar superclasses, como VisualElement, para gravar ações de gatilho que funcionam com uma variedade de controles ou especificar um tipo de controle, como Entry.

  • Substitua o Invoke método – isso é chamado sempre que os critérios de gatilho são atendidos.

  • Outra opção é expor propriedades que podem ser definidas no XAML quando o gatilho é declarado. Para obter um exemplo disso, confira a classe VisualElementPopTriggerAction no respectivo aplicativo de exemplo.

public class NumericValidationTriggerAction : TriggerAction<Entry>
{
    protected override void Invoke (Entry entry)
    {
        double result;
        bool isValid = Double.TryParse (entry.Text, out result);
        entry.TextColor = isValid ? Color.Default : Color.Red;
    }
}

O gatilho de evento pode ser consumido do XAML:

<EventTrigger Event="TextChanged">
    <local:NumericValidationTriggerAction />
</EventTrigger>

Tenha cuidado ao compartilhar gatilhos em um ResourceDictionary, pois uma instância será compartilhada entre os controles para que qualquer estado que está configurado uma vez se aplique a todos.

Observe que os gatilhos de evento não dão suporte a EnterActions e ExitActionsdescritos abaixo.

Vários gatilhos

Um MultiTrigger é semelhante a um Trigger ou DataTrigger, exceto que pode haver mais de uma condição. Todas as condições devem ser verdadeiras antes de Setters serem disparados.

Aqui está um exemplo de um gatilho para um botão que é associado a duas entradas diferentes (email e phone):

<MultiTrigger TargetType="Button">
    <MultiTrigger.Conditions>
        <BindingCondition Binding="{Binding Source={x:Reference email},
                                   Path=Text.Length}"
                               Value="0" />
        <BindingCondition Binding="{Binding Source={x:Reference phone},
                                   Path=Text.Length}"
                               Value="0" />
    </MultiTrigger.Conditions>
    <Setter Property="IsEnabled" Value="False" />
    <!-- multiple Setter elements are allowed -->
</MultiTrigger>

A coleção Conditions também pode conter elementos PropertyCondition como este:

<PropertyCondition Property="Text" Value="OK" />

Criar um gatilho múltiplo que “exige tudo”

O gatilho múltiplo apenas atualiza seu controle quando todas as condições são verdadeiras. O teste para "todos os comprimentos de campo são zero" (como uma página de logon em que todas as entradas devem ser concluídas) é complicado porque você deseja uma condição "em que Text.Length > 0", mas isso não pode ser expresso no XAML.

Isso pode ser feito com um IValueConverter. O código de conversor abaixo transforma o Text.Length que se associa a um bool que indica se um campo está vazio ou não:

public class MultiTriggerConverter : IValueConverter
{
    public object Convert(object value, Type targetType,
        object parameter, CultureInfo culture)
    {
        if ((int)value > 0) // length > 0 ?
            return true;            // some data has been entered
        else
            return false;            // input is empty
    }

    public object ConvertBack(object value, Type targetType,
        object parameter, CultureInfo culture)
    {
        throw new NotSupportedException ();
    }
}

Para usar esse conversor em um gatilho múltiplo, primeiro adicione-o ao dicionário de recursos da página (junto com uma definição de namespace xmlns:local personalizada):

<ResourceDictionary>
   <local:MultiTriggerConverter x:Key="dataHasBeenEntered" />
</ResourceDictionary>

O XAML é mostrado abaixo. Observe as seguintes diferenças do primeiro exemplo de gatilho múltiplo:

  • O botão tem IsEnabled="false" definido por padrão.
  • As condições de vários gatilhos usam o conversor para transformar o Text.Length valor em um boolean.
  • Quando todas as condições são true, o setter faz a propriedade truedo IsEnabled botão .
<Entry x:Name="user" Text="" Placeholder="user name" />

<Entry x:Name="pwd" Text="" Placeholder="password" />

<Button x:Name="loginButton" Text="Login"
        FontSize="Large"
        HorizontalOptions="Center"
        IsEnabled="false">
  <Button.Triggers>
    <MultiTrigger TargetType="Button">
      <MultiTrigger.Conditions>
        <BindingCondition Binding="{Binding Source={x:Reference user},
                              Path=Text.Length,
                              Converter={StaticResource dataHasBeenEntered}}"
                          Value="true" />
        <BindingCondition Binding="{Binding Source={x:Reference pwd},
                              Path=Text.Length,
                              Converter={StaticResource dataHasBeenEntered}}"
                          Value="true" />
      </MultiTrigger.Conditions>
      <Setter Property="IsEnabled" Value="True" />
    </MultiTrigger>
  </Button.Triggers>
</Button>

Essas capturas de tela mostram a diferença entre os dois exemplos de gatilho múltiplo acima. Na parte superior das telas, a entrada de texto em apenas um Entry é suficiente para habilitar o botão Salvar. Na parte inferior das telas, o botão Logon permanece inativo até que ambos os campos contenham dados.

Exemplos de MultiTrigger

EnterActions e ExitActions

Outra maneira de implementar alterações quando ocorre um gatilho é adicionando as coleções EnterActions e ExitActions e especificando as implementações TriggerAction<T>.

A coleção EnterActions é usada para definir um IList de TriggerAction objetos que serão invocados quando a condição do gatilho for atendida. A coleção ExitActions é usada para definir um IList de TriggerAction objetos que serão invocados depois que a condição do gatilho não for mais atendida.

Observação

Os objetos TriggerAction definidos nas coleções EnterActions e ExitActions são ignorados pela classe EventTrigger.

Você pode fornecer eEnterActions e ExitActions também Setterem um gatilho, mas lembre-se de que os Setters são chamados imediatamente (eles não esperam o EnterAction ou ExitAction para concluir). Como alternativa, você pode executar tudo no código e não usar Setters.

<Entry Placeholder="enter job title">
    <Entry.Triggers>
        <Trigger TargetType="Entry"
                 Property="Entry.IsFocused" Value="True">
            <Trigger.EnterActions>
                <local:FadeTriggerAction StartsFrom="0" />
            </Trigger.EnterActions>

            <Trigger.ExitActions>
                <local:FadeTriggerAction StartsFrom="1" />
            </Trigger.ExitActions>
            <!-- You can use both Enter/Exit and Setter together if required -->
        </Trigger>
    </Entry.Triggers>
</Entry>

Como sempre, quando uma classe é referenciada no XAML você deve declarar um namespace como xmlns:local, conforme mostrado aqui:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:WorkingWithTriggers;assembly=WorkingWithTriggers"

O código FadeTriggerAction é mostrado abaixo:

public class FadeTriggerAction : TriggerAction<VisualElement>
{
    public int StartsFrom { set; get; }

    protected override void Invoke(VisualElement sender)
    {
        sender.Animate("FadeTriggerAction", new Animation((d) =>
        {
            var val = StartsFrom == 1 ? d : 1 - d;
            // so i was aiming for a different color, but then i liked the pink :)
            sender.BackgroundColor = Color.FromRgb(1, val, 1);
        }),
        length: 1000, // milliseconds
        easing: Easing.Linear);
    }
}

Gatilhos de estado

Os gatilhos de estado são um grupo especializado de gatilhos que definem as condições sob as quais um VisualState deve ser aplicado.

Os gatilhos de estado são adicionados à StateTriggers coleção de um VisualState. Essa coleção pode conter um único gatilho de estado ou vários gatilhos de estado. Um VisualState será aplicado quando qualquer gatilho de estado na coleção estiver ativo.

Ao usar gatilhos de estado para controlar estados visuais, Xamarin.Forms usa as seguintes regras de precedência para determinar qual gatilho (e correspondente VisualState) estará ativo:

  1. Qualquer gatilho que deriva de StateTriggerBase.
  2. Um AdaptiveTrigger ativado devido à MinWindowWidth condição que está sendo atendida.
  3. Um AdaptiveTrigger ativado devido à MinWindowHeight condição que está sendo atendida.

Se vários gatilhos estiverem ativos simultaneamente (por exemplo, dois gatilhos personalizados), o primeiro gatilho declarado na marcação terá precedência.

Observação

Os gatilhos de estado podem ser definidos em um Styleou diretamente em elementos.

Para obter mais informações sobre estados visuais, consulte Xamarin.Forms Visual State Manager.

Gatilho de estado

A StateTrigger classe , que deriva da StateTriggerBase classe , tem uma IsActive propriedade associável. Um StateTrigger dispara uma VisualState alteração quando a propriedade altera o IsActive valor.

A StateTriggerBase classe , que é a classe base para todos os gatilhos de estado, tem uma IsActive propriedade e um IsActiveChanged evento. Esse evento é acionado sempre que ocorre uma VisualState alteração. Além disso, a StateTriggerBase classe tem métodos e OnDetached substituíveisOnAttached.

Importante

A StateTrigger.IsActive propriedade associável oculta a propriedade herdada StateTriggerBase.IsActive .

O exemplo XAML a seguir mostra um Style que inclui StateTrigger objetos:

<Style TargetType="Grid">
    <Setter Property="VisualStateManager.VisualStateGroups">
        <VisualStateGroupList>
            <VisualStateGroup>
                <VisualState x:Name="Checked">
                    <VisualState.StateTriggers>
                        <StateTrigger IsActive="{Binding IsToggled}"
                                      IsActiveChanged="OnCheckedStateIsActiveChanged" />
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Property="BackgroundColor"
                                Value="Black" />
                    </VisualState.Setters>
                </VisualState>
                <VisualState x:Name="Unchecked">
                    <VisualState.StateTriggers>
                        <StateTrigger IsActive="{Binding IsToggled, Converter={StaticResource inverseBooleanConverter}}"
                                      IsActiveChanged="OnUncheckedStateIsActiveChanged" />
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Property="BackgroundColor"
                                Value="White" />
                    </VisualState.Setters>
                </VisualState>
            </VisualStateGroup>
        </VisualStateGroupList>
    </Setter>
</Style>

Neste exemplo, os objetos de destino Grid implícitosStyle. Quando a IsToggled propriedade do objeto associado é true, a cor da tela de fundo do Grid é definida como preta. Quando a IsToggled propriedade do objeto associado se torna false, uma VisualState alteração é disparada e a cor da tela de fundo do Grid torna-se branca.

Além disso, sempre que ocorre uma VisualState alteração, o IsActiveChanged evento para o VisualState é acionado. Cada VisualState um registra um manipulador de eventos para este evento:

void OnCheckedStateIsActiveChanged(object sender, EventArgs e)
{
    StateTriggerBase stateTrigger = sender as StateTriggerBase;
    Console.WriteLine($"Checked state active: {stateTrigger.IsActive}");
}

void OnUncheckedStateIsActiveChanged(object sender, EventArgs e)
{
    StateTriggerBase stateTrigger = sender as StateTriggerBase;
    Console.WriteLine($"Unchecked state active: {stateTrigger.IsActive}");
}

Neste exemplo, quando um manipulador para o IsActiveChanged evento é acionado, o manipulador gera se o VisualState está ativo ou não. Por exemplo, as seguintes mensagens são enviadas para a janela do console ao alterar do Checked estado visual para o Unchecked estado visual:

Checked state active: False
Unchecked state active: True

Observação

Gatilhos de estado personalizados podem ser criados derivando da StateTriggerBase classe e substituindo os métodos e OnDetached para executar todos os OnAttached registros e limpeza necessários.

Gatilho adaptável

Um AdaptiveTrigger dispara uma VisualState alteração quando a janela é uma altura ou largura especificada. Esse gatilho tem duas propriedades associáveis:

Observação

O AdaptiveTrigger deriva da StateTriggerBase classe e, portanto, pode anexar um manipulador de eventos ao IsActiveChanged evento.

O exemplo XAML a seguir mostra um Style que inclui AdaptiveTrigger objetos :

<Style TargetType="StackLayout">
    <Setter Property="VisualStateManager.VisualStateGroups">
        <VisualStateGroupList>
            <VisualStateGroup>
                <VisualState x:Name="Vertical">
                    <VisualState.StateTriggers>
                        <AdaptiveTrigger MinWindowWidth="0" />
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Property="Orientation"
                                Value="Vertical" />
                    </VisualState.Setters>
                </VisualState>
                <VisualState x:Name="Horizontal">
                    <VisualState.StateTriggers>
                        <AdaptiveTrigger MinWindowWidth="800" />
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Property="Orientation"
                                Value="Horizontal" />
                    </VisualState.Setters>
                </VisualState>
            </VisualStateGroup>
        </VisualStateGroupList>
    </Setter>
</Style>

Neste exemplo, os objetos de destino StackLayout implícitosStyle. Quando a largura da janela estiver entre 0 e 800 unidades independentes do dispositivo, StackLayout os objetos aos quais o Style é aplicado terão uma orientação vertical. Quando a largura da janela é >= 800 unidades independentes do dispositivo, a VisualState alteração é disparada e a StackLayout orientação muda para horizontal:

AdaptiveTriggerExemplo de de Exemplo de StackLayout VisualState

As MinWindowHeight propriedades e MinWindowWidth podem ser usadas de forma independente ou em conjunto umas com as outras. O XAML a seguir mostra um exemplo de configuração de ambas as propriedades:

<AdaptiveTrigger MinWindowWidth="800"
                 MinWindowHeight="1200"/>

Neste exemplo, o AdaptiveTrigger indica que o correspondente VisualState será aplicado quando a largura da janela atual for >= 800 unidades independentes do dispositivo e a altura da janela atual for >= 1200 unidades independentes do dispositivo.

Comparar gatilho de estado

O CompareStateTrigger dispara uma VisualState alteração quando uma propriedade é igual a um valor específico. Esse gatilho tem duas propriedades associáveis:

  • Property, do tipo object, que indica a propriedade que está sendo comparada pelo gatilho.
  • Value, do tipo object, que indica o valor no qual o VisualState deve ser aplicado.

Observação

O CompareStateTrigger deriva da StateTriggerBase classe e, portanto, pode anexar um manipulador de eventos ao IsActiveChanged evento.

O exemplo XAML a seguir mostra um Style que inclui CompareStateTrigger objetos :

<Style TargetType="Grid">
    <Setter Property="VisualStateManager.VisualStateGroups">
        <VisualStateGroupList>
            <VisualStateGroup>
                <VisualState x:Name="Checked">
                    <VisualState.StateTriggers>
                        <CompareStateTrigger Property="{Binding Source={x:Reference checkBox}, Path=IsChecked}"
                                             Value="True" />
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Property="BackgroundColor"
                                Value="Black" />
                    </VisualState.Setters>
                </VisualState>
                <VisualState x:Name="Unchecked">
                    <VisualState.StateTriggers>
                        <CompareStateTrigger Property="{Binding Source={x:Reference checkBox}, Path=IsChecked}"
                                             Value="False" />
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Property="BackgroundColor"
                                Value="White" />
                    </VisualState.Setters>
                </VisualState>
            </VisualStateGroup>
        </VisualStateGroupList>
    </Setter>
</Style>
...
<Grid>
    <Frame BackgroundColor="White"
           CornerRadius="12"
           Margin="24"
           HorizontalOptions="Center"
           VerticalOptions="Center">
        <StackLayout Orientation="Horizontal">
            <CheckBox x:Name="checkBox"
                      VerticalOptions="Center" />
            <Label Text="Check the CheckBox to modify the Grid background color."
                   VerticalOptions="Center" />
        </StackLayout>
    </Frame>
</Grid>

Neste exemplo, os objetos de destino Grid implícitosStyle. Quando a IsChecked propriedade do CheckBox é false, a cor da tela de fundo do Grid é definida como branca. Quando a CheckBox.IsChecked propriedade se torna true, uma VisualState alteração é disparada e a cor da tela de fundo do Grid se torna preta:

Captura de tela de uma alteração de estado visual disparada, no iOS e no Android, com o gatilho desmarcado.Captura de tela de uma alteração de estado visual disparada, no iOS e no Android, com o gatilho verificado.

Gatilho de estado do dispositivo

O DeviceStateTrigger dispara uma VisualState alteração com base na plataforma do dispositivo em que o aplicativo está sendo executado. Esse gatilho tem uma única propriedade associável:

  • Device, do tipo string, que indica a plataforma do dispositivo na qual o VisualState deve ser aplicado.

Observação

O DeviceStateTrigger deriva da StateTriggerBase classe e, portanto, pode anexar um manipulador de eventos ao IsActiveChanged evento.

O exemplo XAML a seguir mostra um Style que inclui DeviceStateTrigger objetos :

<Style x:Key="DeviceStateTriggerPageStyle"
       TargetType="ContentPage">
    <Setter Property="VisualStateManager.VisualStateGroups">
        <VisualStateGroupList>
            <VisualStateGroup>
                <VisualState x:Name="iOS">
                    <VisualState.StateTriggers>
                        <DeviceStateTrigger Device="iOS" />
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Property="BackgroundColor"
                                Value="Silver" />
                    </VisualState.Setters>
                </VisualState>
                <VisualState x:Name="Android">
                    <VisualState.StateTriggers>
                        <DeviceStateTrigger Device="Android" />
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Property="BackgroundColor"
                                Value="#2196F3" />
                    </VisualState.Setters>
                </VisualState>
                <VisualState x:Name="UWP">
                    <VisualState.StateTriggers>
                        <DeviceStateTrigger Device="UWP" />
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Property="BackgroundColor"
                                Value="Aquamarine" />
                    </VisualState.Setters>
                </VisualState>
            </VisualStateGroup>
        </VisualStateGroupList>
    </Setter>
</Style>

Neste exemplo, os objetos de destino ContentPage explícitosStyle. ContentPage os objetos que consomem o estilo definem sua cor da tela de fundo como prata no iOS, para azul claro no Android e para aquamarine na UWP. As capturas de tela a seguir mostram as páginas resultantes no iOS e no Android:

Captura de tela de uma alteração de estado visual disparada, no exemplo deviceStateTrigger do iOS e Android

Gatilho de estado de orientação

O OrientationStateTrigger dispara uma VisualState alteração quando a orientação do dispositivo é alterada. Esse gatilho tem uma única propriedade associável:

Observação

O OrientationStateTrigger deriva da StateTriggerBase classe e, portanto, pode anexar um manipulador de eventos ao IsActiveChanged evento.

O exemplo XAML a seguir mostra um Style que inclui OrientationStateTrigger objetos :

<Style x:Key="OrientationStateTriggerPageStyle"
       TargetType="ContentPage">
    <Setter Property="VisualStateManager.VisualStateGroups">
        <VisualStateGroupList>
            <VisualStateGroup>
                <VisualState x:Name="Portrait">
                    <VisualState.StateTriggers>
                        <OrientationStateTrigger Orientation="Portrait" />
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Property="BackgroundColor"
                                Value="Silver" />
                    </VisualState.Setters>
                </VisualState>
                <VisualState x:Name="Landscape">
                    <VisualState.StateTriggers>
                        <OrientationStateTrigger Orientation="Landscape" />
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Property="BackgroundColor"
                                Value="White" />
                    </VisualState.Setters>
                </VisualState>
            </VisualStateGroup>
        </VisualStateGroupList>
    </Setter>
</Style>

Neste exemplo, os objetos de destino ContentPage explícitosStyle. ContentPage os objetos que consomem o estilo definem a cor da tela de fundo como prata quando a orientação é retrato e definem a cor da tela de fundo como branca quando a orientação é paisagem.