Partilhar via


VisualStateManager.GoToState(Control, String, Boolean) Método

Definição

Faz a transição de um controle entre dois estados, solicitando um novo VisualState por nome.

public:
 static bool GoToState(Control ^ control, Platform::String ^ stateName, bool useTransitions);
 static bool GoToState(Control const& control, winrt::hstring const& stateName, bool const& useTransitions);
public static bool GoToState(Control control, string stateName, bool useTransitions);
function goToState(control, stateName, useTransitions)
Public Shared Function GoToState (control As Control, stateName As String, useTransitions As Boolean) As Boolean

Parâmetros

control
Control

O controle para fazer a transição entre estados.

stateName
String

Platform::String

winrt::hstring

O estado para fazer a transição.

useTransitions
Boolean

bool

true para usar um VisualTransition para fazer a transição entre estados. false para ignorar o uso de transições e ir diretamente para o estado solicitado. O padrão é false.

Retornos

Boolean

bool

true se o controle fizer a transição com êxito para o novo estado ou se já estiver usando esse estado; caso contrário, false.

Exemplos

Este exemplo demonstra a lógica de controle que usa o método GoToState para fazer a transição entre estados.

private void UpdateStates(bool useTransitions)
{
    if (Value >= 0)
    {
        VisualStateManager.GoToState(this, "Positive", useTransitions);
    }
    else
    {
        VisualStateManager.GoToState(this, "Negative", useTransitions);
    }

    if (isFocused)
    {
        VisualStateManager.GoToState(this, "Focused", useTransitions);
    }
    else
    {
        VisualStateManager.GoToState(this, "Unfocused", useTransitions);
    }

}
Private Sub UpdateStates(ByVal useTransitions As Boolean)
    If Value >= 0 Then
        VisualStateManager.GoToState(Me, "Positive", useTransitions)
    Else
        VisualStateManager.GoToState(Me, "Negative", useTransitions)
    End If

    If isFocused Then
        VisualStateManager.GoToState(Me, "Focused", useTransitions)
    Else
        VisualStateManager.GoToState(Me, "Unfocused", useTransitions)
    End If

End Sub
<ResourceDictionary 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="using:NumericUpDownCustomControl"
    >
    <Style TargetType="local:NumericUpDown">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:NumericUpDown">
                    <Grid  Margin="3" 
                Background="{TemplateBinding Background}">
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="ValueStates">
                                
                                <!--Make the Value property red when it is negative.-->
                                <VisualState x:Name="Negative">
                                    <Storyboard>
                                        <ColorAnimation To="Red"
                                    Storyboard.TargetName="TextBlock" 
                                    Storyboard.TargetProperty="(Foreground).(SolidColorBrush.Color)"/>
                                    </Storyboard>
                                </VisualState>
                                <!--Return the control to its initial state by
                    return the TextBlock Foreground to its 
                    original color.-->
                                <VisualState x:Name="Positive" />
                            </VisualStateGroup>

                            <VisualStateGroup x:Name="FocusStates">
                                <!--Add a focus rectangle to highlight the entire control
                    when it has focus.-->
                                <VisualState x:Name="Focused">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="FocusVisual" 
                                                   Storyboard.TargetProperty="Visibility" Duration="0">
                                            <DiscreteObjectKeyFrame KeyTime="0">
                                                <DiscreteObjectKeyFrame.Value>
                                                    <Visibility>Visible</Visibility>
                                                </DiscreteObjectKeyFrame.Value>
                                            </DiscreteObjectKeyFrame>
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                                <!--Return the control to its initial state by
                    hiding the focus rectangle.-->
                                <VisualState x:Name="Unfocused"/>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>

                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition/>
                                <RowDefinition/>
                            </Grid.RowDefinitions>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition/>
                                <ColumnDefinition/>
                            </Grid.ColumnDefinitions>

                            <Border BorderThickness="1" BorderBrush="Gray" 
                    Margin="7,2,2,2" Grid.RowSpan="2" 
                    Background="#E0FFFFFF"
                    VerticalAlignment="Center" 
                    HorizontalAlignment="Stretch">
                                <TextBlock x:Name="TextBlock" TextAlignment="Center" Padding="5"
                           Foreground="{TemplateBinding Foreground}"/>

                            </Border>

                            <RepeatButton Content="Up" Margin="2,5,5,0" 
                          x:Name="UpButton"
                          Grid.Column="1" Grid.Row="0"
                          Foreground="Green"/>
                            <RepeatButton Content="Down" Margin="2,0,5,5" 
                          x:Name="DownButton"
                          Grid.Column="1" Grid.Row="1" 
                          Foreground="Green"/>

                            <Rectangle Name="FocusVisual" Grid.ColumnSpan="2" Grid.RowSpan="2" 
                       Stroke="Red" StrokeThickness="1"  
                       Visibility="Collapsed"/>
                        </Grid>

                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    
</ResourceDictionary>

Comentários

Esse método é usado pela lógica de controle. Normalmente, você só precisará dele se estiver escrevendo um controle personalizado ou se estiver usando a lógica no nível do aplicativo para estados de exibição (como atualizar o conteúdo do aplicativo para alterações no tamanho ou orientação da janela do aplicativo).

Quando você chama esse método, espera-se que haja um VisualState com um valor x:Name que corresponda ao seu valor stateName , em algum lugar no modelo de controle para o controle identificado pelo controle ou como um recurso para seu aplicativo. Se não houver, você não receberá exceções, mas o valor retornado será false. O estado nomeado por stateName pode estar em qualquer um dos elementos VisualStateGroup no modelo para o Control especificado. Cabe a você controlar quais estados estão em que VisualStateGroup e saber qual estado é descarregado quando você especifica um novo estado desse grupo.

Normalmente, o ControlTemplate que contém os estados visuais conforme referenciado pelo nome ao usar GoToState não é definido especificamente para essa instância de controle. Em vez disso, os estados visuais são do estilo de controle padrão carregado como o estilo implícito para todas as instâncias desse controle. Para obter mais informações sobre o conceito de estilo implícito, consulte Início Rápido: modelos de controle.

O VisualStateManager dá suporte a dois recursos importantes para autores de controle e para desenvolvedores de aplicativos que estão aplicando um modelo personalizado a um controle:

  • Autores de controle ou desenvolvedores de aplicativos adicionam elementos de objeto VisualStateGroup ao elemento raiz de uma definição de modelo de controle em XAML, usando a propriedade anexada VisualStateManager.VisualStateGroups . Dentro de um elemento VisualStateGroup , cada VisualState representa um estado visual discreto de um controle. Cada VisualState tem um nome que representa um estado de interface do usuário que pode ser alterado pelo usuário ou alterado pela lógica de controle. Um VisualState consiste principalmente em um Storyboard. Este Storyboard tem como destino valores de propriedade de dependência individuais que devem ser aplicados sempre que o controle estiver nesse estado visual.
  • Controlar a transição de autores ou desenvolvedores de aplicativos entre esses estados chamando o método GoToState estático de VisualStateManager. Os autores de controle fazem isso sempre que a lógica de controle manipula eventos que indicam uma alteração de estado ou a lógica de controle inicia uma alteração de estado por si só. É mais comum que o código de definição de controle faça isso em vez do código do aplicativo, para que todos os estados visuais possíveis e suas transições e condições de gatilho estejam lá por padrão para o código do aplicativo. Ou, é o código do aplicativo que está alterando os estados visuais, para gerenciar estados de exibição no nível do aplicativo em resposta a alterações controladas pelo usuário no tamanho ou orientação da janela do aplicativo main.

Quando você chama GoToState para alterar o estado visual de um controle, o VisualStateManager executa estas ações:

  • Primeiro, é determinado se existe um estado que corresponda a stateName . Caso contrário, nada acontece e o método retorna false.
  • Se o VisualState como nomeado por stateName existir e tiver um Storyboard, o storyboard começará.
  • Se o VisualState que o controle estava usando desse mesmo VisualStateGroup antes do estado recém-solicitado tiver um Storyboard, esse storyboard será interrompido. Além das propriedades específicas às quais o novo VisualState aplica uma animação, o controle é revertido para os estados inicialmente carregados do modelo de controle e sua composição.

Se o controle já estiver no VisualState solicitado como stateName, GoToState retornará true, mas não haverá nenhuma ação (o storyboard não será reiniciado).

Um padrão de implementação de controle comum é definir um único método privado da classe de controle que cuida de todas as possíveis alterações de VisualState para o controle. Qual estado visual usar é determinado verificando as propriedades do controle. Essas propriedades podem ser públicas ou privadas. Os valores das propriedades são ajustados por manipuladores na lógica de controle para eventos como OnGotFocus e são verificados just-in-time imediatamente antes de definir o estado visual. O exemplo de código neste tópico usa esse padrão de implementação. Como alternativa, você pode chamar GoToState para estados individuais de dentro de manipuladores de eventos, de substituições do manipulador de eventos de controle (os métodos OnEvent ) ou de métodos auxiliares que são chamados por todos os possíveis impulsos para alterar estados (eventos controlados pelo usuário, eventos de automação, lógica de inicialização).

Você também pode chamar GoToState de dentro da implementação PropertyChangedCallback para uma propriedade de dependência personalizada.

Estados visuais e transições

Além dos estados visuais, o modelo de estado visual também inclui transições. As transições são ações de animação controladas por um Storyboard que ocorrem entre cada estado visual quando o estado é alterado. A transição pode ser definida de forma diferente para cada combinação de estado inicial e final, conforme definido pelo conjunto de estados visuais do controle. As transições são definidas pela propriedade Transitions de VisualStateGroup e geralmente são definidas em XAML. A maioria dos modelos de controle padrão não define transições e, nesse caso, as transições entre estados ocorrem instantaneamente. Para obter mais informações, consulte VisualTransition.

Um VisualTransition também pode ser definido de modo que produza uma transição implícita. Qualquer propriedade de dependência especificamente direcionada para animação nos estados visuais De ouPara de um VisualTransition e que tenha valores diferentes em toda a alteração de estado pode ser animada com uma animação de transição implícita. Essa animação gerada faz a transição entre o valor do estado De e o valor de estado Para dessa propriedade usando interpolação. A animação de transição implícita dura o tempo declarado pelo valor GeneratedDuration de um VisualTransition. Transições implícitas se aplicam apenas a propriedades que são um valor Double, Color ou Point . Em outras palavras, a propriedade deve ser possível animar implicitamente usando um DoubleAnimation, PointAnimation ou ColorAnimation. Para obter mais informações, consulte GeneratedDuration.

Eventos para alterações de estado visual

CurrentStateChanging é acionado quando o controle começa a fazer a transição de estados conforme solicitado pela chamada GoToState. Se um VisualTransition for aplicado à alteração de estado, esse evento ocorrerá quando a transição for iniciada.

CurrentStateChanged é acionado depois que o controle está no estado conforme solicitado pela chamada de GoToState, assim como o novo Storyboard começa. Nenhum evento é acionado na conclusão do novo storyboard.

Se um VisualTransition não for aplicado, CurrentStateChanging e CurrentStateChanged serão acionados em sucessão rápida, mas serão garantidos nessa ordem se ambos ocorrerem.

No entanto, se uma transição de alteração de estado for interrompida por uma nova chamada GoToState, o evento CurrentStateChanged nunca será gerado para a primeira transição de estado. Uma nova série de eventos é disparada para a próxima alteração de estado solicitada.

OnApplyTemplate não é invocado para alterações de estado visual. OnApplyTemplate só é invocado para a carga inicial de um controle em uma interface do usuário XAML.

Atribuir os estados visuais nomeados de um controle personalizado

Se você estiver definindo um controle personalizado que tenha estados visuais em seu modelo de controle XAML, é uma prática recomendada atribuir a classe de controle para indicar aos consumidores quais estados visuais estão disponíveis. Para fazer isso, aplique um ou mais atributos TemplateVisualState no nível de classe do código de definição de controle. Cada atributo deve especificar o atributo x:Name do estado, que é o valor stateName que um consumidor de controle passaria em uma chamada GoToState para usar esse estado visual. Se o VisualState fizer parte de um VisualStateGroup, isso também deverá ser indicado na definição de atributo.

Um conceito relacionado é que os autores de controle devem atribuir os nomes das partes de controle de chave usando TemplatePartAttribute. Isso será muito útil se os consumidores de controle quiserem acessar partes nomeadas do escopo do modelo depois que o modelo for aplicado. TemplateVisualStateAttribute e TemplatePartAttribute combinados ajudam a definir o contrato de controle para um controle.

VisualStateManager personalizado

Como um cenário avançado, é possível derivar de VisualStateManager e alterar o comportamento padrão de GoToState. A classe derivada deve substituir o método GoToStateCore protegido. Qualquer instância do VisualStateManager personalizado usa essa lógica Core quando seu método GoToState é chamado.

Estados visuais para estados de exibição de aplicativo

Os estados visuais não são necessariamente para controles personalizados. Você pode usar estados visuais de novos modelos de controle que você aplica a qualquer instância de Controle em que você está substituindo o modelo padrão definindo a propriedade Template . Para configurar isso, você deve definir o modelo de controle e os estados visuais que está planejando usar como um recurso style que está em Page.Resources ou Application.Resources. É sempre melhor começar com uma cópia do modelo padrão e modificar apenas determinados aspectos do modelo ou até mesmo apenas modificar alguns dos estados visuais e deixar a composição básica em paz. Para obter mais informações, consulte Guia de início rápido: modelos de controle.

Os estados visuais podem ser usados para alterar as propriedades de uma Página ou controles dentro da página para considerar a orientação da janela do aplicativo. A composição ou os valores de propriedade relacionados ao layout do controle podem mudar dependendo se a orientação geral é retrato ou paisagem. Para obter mais informações sobre esse cenário para GoToState, consulte Início Rápido: Projetando aplicativos para diferentes tamanhos de janela.

Estados visuais para elementos que não são controles

Às vezes, os estados visuais são úteis para cenários em que você deseja alterar o estado de alguma área da interface do usuário que não é imediatamente uma subclasse Control . Você não pode fazer isso diretamente porque o parâmetro de controle do método GoToState requer uma subclasse Control , que se refere ao objeto sobre o qual o VisualStateManager atua. Page é uma subclasse control e é bastante raro que você esteja mostrando a interface do usuário em um contexto em que você não tem uma Página ou sua raiz Window.Content não é uma subclasse Control . Recomendamos que você defina um UserControl personalizado para ser a raiz Window.Content ou ser um contêiner para outro conteúdo ao qual você deseja aplicar estados (como um Painel). Em seguida, você pode chamar GoToState em seu UserControl e aplicar estados, independentemente de o restante do conteúdo ser um Controle. Por exemplo, você pode aplicar estados visuais à interface do usuário que, de outra forma, consistem em apenas um SwapChainPanel , desde que você tenha colocado isso em seu UserControl e declarado estados nomeados que se aplicam às propriedades do UserControl pai ou da parte nomeada SwapChainPanel do modelo.

Aplica-se a

Confira também