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);
    }

}
<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 x:Name valor que corresponda ao seu stateName valor, em algum lugar no modelo de controle para o controle identificado por controlou 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 Controle especificado. Cabe a você acompanhar 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 referenciados 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 Modelos de controle XAML.

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:

  • Os 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 VisualStateManager.VisualStateGroups propriedade anexada. Dentro de um VisualStateGroup elemento , cada VisualState representa um estado visual discreto de um controle. Cada VisualState um 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. Isso 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 correspondente 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 do 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 de 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 do 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 de manipulador de eventos de controle (os métodos OnEvent ) ou de métodos auxiliares que são chamados por todo o impulso possível 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 estado final, conforme definido pelo conjunto de estados visuais do controle. As transições são definidas pela propriedade Transitions do 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 tem 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 de estado De e o valor para estado de uma 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 só se aplicam a propriedades que são um valor Double, Color ou Point . Em outras palavras, a propriedade deve ser possível animar implicitamente usando 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 GoToState chamada. Se um VisualTransition for aplicado à alteração de estado, esse evento ocorrerá quando a transição começar.

CurrentStateChanged é acionado depois que o controle está no estado conforme solicitado pela GoToState chamada, 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 rápida sucessão, 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 GoToState chamada, 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 tem estados visuais em seu modelo de controle XAML, é uma prática recomendada atribuir a classe de controle para indicar para controlar os 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 GoToState chamada 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 do VisualStateManager e alterar o comportamento padrão GoToState . A classe derivada deve substituir o método GoToStateCore protegido. Qualquer instância do VisualStateManager personalizado usa essa lógica Core quando seu GoToState método é 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 você 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 Modelos de controle XAML.

Os estados visuais podem ser usados para alterar 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 Layouts responsivos com XAML.

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

Os estados visuais às vezes 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 GoToState método requer uma Control subclasse, que se refere ao objeto em que o VisualStateManager atua. Page é uma Control subclasse e é bastante raro que você esteja mostrando a interface do usuário em um contexto em que você não tem uma Pageou sua raiz Window.Content não é uma Control subclasse. Recomendamos que você defina um UserControl personalizado para ser a Window.Content raiz ou ser um contêiner para outro conteúdo ao qual você deseja aplicar estados (como um Painel). Em seguida, você pode chamar GoToState seus UserControl estados e aplicar, independentemente de o restante do conteúdo ser um Control. Por exemplo, você pode aplicar estados visuais à interface do usuário que, de outra forma, consiste em apenas um SwapChainPanel , desde que você coloque isso em seus UserControl estados nomeados e declarados que se aplicam às propriedades do pai UserControl ou da parte nomeada SwapChainPanel do modelo.

Aplica-se a

Confira também