Compartir a través de


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

Definición

Realiza una transición de un control entre dos estados mediante la solicitud de un nuevo Objeto VisualState por nombre.

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

Control del que se va a realizar la transición entre estados.

stateName
String

Platform::String

winrt::hstring

El estado al que se realiza la transición.

useTransitions
Boolean

bool

true para usar un objeto VisualTransition para realizar la transición entre estados. false para omitir el uso de transiciones y ir directamente al estado solicitado. El valor predeterminado es false.

Devoluciones

Boolean

bool

true si el control realiza correctamente la transición al nuevo estado o ya estaba usando ese estado; de lo contrario, false.

Ejemplos

En este ejemplo se muestra la lógica de control que usa el método GoToState para realizar la transición 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>

Comentarios

Esta lógica de control usa este método. Normalmente, solo lo necesita si está escribiendo un control personalizado o si usa lógica de nivel de aplicación para los estados de vista (como actualizar el contenido de la aplicación para los cambios en el tamaño o la orientación de la ventana de la aplicación).

Al llamar a este método, se espera que haya un objeto VisualState con un x:Name valor que coincida con el stateName valor, en algún lugar de la plantilla de control para el control identificado por controlo como un recurso para la aplicación. Si no lo hay, no obtiene excepciones, pero el valor devuelto será false. El estado denominado por stateName puede estar en cualquiera de los elementos VisualStateGroup de la plantilla para el control especificado. Es necesario realizar un seguimiento de los estados en los que VisualStateGroup se encuentran y saber qué estado se descarga al especificar un nuevo estado de ese grupo.

Normalmente, controlTemplate que contiene los estados visuales a los que se hace referencia por nombre cuando el uso GoToState no está definido específicamente para esa instancia de control. En su lugar, los estados visuales proceden del estilo de control predeterminado que se carga como estilo implícito para todas las instancias de ese control. Para obtener más información sobre el concepto de estilo implícito, consulta Plantillas de control XAML.

VisualStateManager admite dos características importantes para los autores de controles y para los desarrolladores de aplicaciones que aplican una plantilla personalizada a un control:

  • Los autores de controles o desarrolladores de aplicaciones agregan elementos de objeto VisualStateGroup al elemento raíz de una definición de plantilla de control en XAML mediante la VisualStateManager.VisualStateGroups propiedad adjunta. Dentro de un VisualStateGroup elemento, cada Objeto VisualState representa un estado visual discreto de un control. Cada VisualState tiene un nombre que es representativo de un estado de interfaz de usuario que el usuario puede cambiar o cambiar por lógica de control. Consta VisualState principalmente de un guión gráfico. Esto Storyboard tiene como destino los valores de propiedad de dependencia individuales que se deben aplicar cada vez que el control está en ese estado visual.
  • Los autores de controles o desarrolladores de aplicaciones realizan la transición entre estos estados mediante una llamada al método GoToState estático de VisualStateManager. Los autores de controles lo hacen cada vez que la lógica de control controla eventos que indican un cambio de estado o la lógica de control inicia un cambio de estado por sí mismo. Es más común que el código de definición de control haga esto en lugar del código de la aplicación, de modo que todos los estados visuales posibles y sus transiciones y condiciones de desencadenador estén allí de forma predeterminada para el código de la aplicación. O bien, es el código de la aplicación que está cambiando los estados visuales, para administrar los estados de vista de nivel de aplicación en respuesta a los cambios controlados por el usuario en el tamaño o la orientación de la ventana principal de la aplicación.

Cuando se llama GoToState a para cambiar el estado visual de un control, VisualStateManager realiza estas acciones:

  • En primer lugar, se determina si existe un estado que coincide stateName . Si no es así, no sucede nada y el método devuelve false.
  • Si el objeto VisualState denominado por stateName existe y tiene un Guión gráfico, comienza el guión gráfico.
  • Si el objeto VisualState que el control usaba desde ese mismo VisualStateGroup antes del estado recién solicitado tiene un Guión gráfico, ese guión gráfico se detiene. Aparte de las propiedades específicas a las que el nuevo VisualState aplica una animación, el control vuelve a los estados cargados inicialmente de la plantilla de control y su composición.

Si el control ya está en visualState solicitado como stateName, devuelve true, GoToState pero no hay ninguna acción (el guión gráfico no se reiniciará).

Un patrón de implementación de control común es definir un único método privado de la clase de control que se encarga de todos los posibles cambios de VisualState para el control. El estado visual que se va a usar se determina comprobando las propiedades del control. Estas propiedades pueden ser públicas o privadas. Los controladores ajustan los valores de las propiedades en la lógica de control para eventos como OnGotFocus y se comprueban just-in-time inmediatamente antes de establecer el estado visual. En el ejemplo de código de este tema se usa este patrón de implementación. Como alternativa, puede llamar a GoToState para estados individuales desde controladores de eventos, desde invalidaciones del controlador de eventos de control (los métodos OnEvent ) o desde métodos auxiliares a los que llaman todos los posibles impulsos para los estados cambiantes (eventos controlados por el usuario, eventos de automatización, lógica de inicialización).

También puede llamar a GoToState desde la implementación propertyChangedCallback para una propiedad de dependencia personalizada.

Estados visuales y transiciones

Además de los estados visuales, el modelo de estado visual también incluye transiciones. Las transiciones son acciones de animación controladas por un Guión gráfico que se produce entre cada estado visual cuando se cambia el estado. La transición se puede definir de forma diferente para cada combinación de estado inicial y estado final según lo definido por el conjunto de estados visuales del control. Las transiciones se definen mediante la propiedad Transitions de VisualStateGroup y normalmente se definen en XAML. La mayoría de las plantillas de control predeterminadas no definen transiciones y, en este caso, las transiciones entre estados se producen instantáneamente. Para obtener más información, consulta VisualTransition.

También se puede definir una visualTransition de modo que genere una transición implícita. Cualquier propiedad de dependencia destinada específicamente a la animación en los estados visuales From oTo de y VisualTransition tiene valores diferentes en el cambio de estado se puede animar con una animación de transición implícita. Esta animación generada pasa entre el valor de estado From y el valor de estado To de dicha propiedad mediante interpolación. La animación de transición implícita dura la hora indicada por el valor GeneratedDuration de .VisualTransition Las transiciones implícitas solo se aplican a las propiedades que son un valor Double, Color o Point . Es decir, la propiedad debe ser posible animar implícitamente mediante doubleAnimation, PointAnimation o ColorAnimation. Para obtener más información, consulta GeneratedDuration.

Eventos para cambios de estado visual

CurrentStateChanging se desencadena cuando el control comienza a realizar la transición de estados según lo solicitado por la GoToState llamada. Si se aplica un objeto VisualTransition al cambio de estado, este evento se produce cuando comienza la transición.

CurrentStateChanged se activa después de que el control esté en el estado solicitado por la GoToState llamada, al igual que comienza el nuevo Guión gráfico . No se desencadena ningún evento en la finalización del nuevo guión gráfico.

Si no se aplica una visualTransition , CurrentStateChanging y CurrentStateChanged se activan en sucesión rápida, pero se garantizan en ese orden si se producen ambos.

Sin embargo, si una nueva GoToState llamada interrumpe una transición de cambio de estado, el evento CurrentStateChanged nunca se genera para la primera transición de estado. Se desencadena una nueva serie de eventos para el siguiente cambio de estado solicitado.

OnApplyTemplate no se invoca para cambios de estado visual. OnApplyTemplate solo se invoca para la carga inicial de un control en una interfaz de usuario XAML.

Atribuir los estados visuales con nombre de un control personalizado

Si va a definir un control personalizado que tiene estados visuales en su XAML de plantilla de control, se recomienda atribuir la clase de control para indicar a los consumidores qué estados visuales están disponibles. Para ello, aplique uno o varios atributos TemplateVisualState en el nivel de clase del código de definición de control. Cada atributo debe especificar el atributo x:Name del estado, que es el valor stateName que un consumidor de control pasaría una GoToState llamada para usar ese estado visual. Si VisualState forma parte de un objeto VisualStateGroup, también debe indicarse en la definición de atributo.

Un concepto relacionado es que los autores de controles deben atribuir los nombres de los elementos de control clave mediante TemplatePartAttribute. Esto es muy útil si los consumidores de control quieren acceder a elementos con nombre desde el ámbito de la plantilla después de aplicar la plantilla. TemplateVisualStateAttribute y TemplatePartAttribute ayudan combinadas a definir el contrato de control para un control.

VisualStateManager personalizado

Como escenario avanzado, es posible derivar de VisualStateManager y cambiar el comportamiento predeterminado GoToState . La clase derivada debe invalidar el método GoToStateCore protegido. Cualquier instancia de VisualStateManager personalizada usa esta lógica core cuando se llama a su GoToState método.

Estados visuales para los estados de vista de la aplicación

Los estados visuales no son necesariamente para los controles personalizados. Puede usar estados visuales de nuevas plantillas de control que aplique a cualquier instancia de Control en la que reemplace la plantilla predeterminada estableciendo la propiedad Template . Para configurarlo, debe definir la plantilla de control y los estados visuales en los que planea usar como un recurso style que se encuentra en Page.Resources o Application.Resources. Siempre es mejor empezar con una copia de la plantilla predeterminada y modificar solo ciertos aspectos de la plantilla o incluso modificar algunos de los estados visuales y dejar solo la composición básica. Para obtener más información, consulta Plantillas de control XAML.

Los estados visuales se pueden usar para cambiar las propiedades de una página o controles dentro de la página para tener en cuenta la orientación de la ventana de la aplicación. La composición o los valores de propiedad relacionados con el diseño del control pueden cambiar en función de si la orientación general es vertical o horizontal. Para obtener más información sobre este escenario para GoToState, consulta Diseños dinámicos con XAML.

Estados visuales de los elementos que no son controles

Los estados visuales a veces son útiles para escenarios en los que desea cambiar el estado de algún área de la interfaz de usuario que no es inmediatamente una subclase Control . No puede hacerlo directamente porque el parámetro de control del GoToState método requiere una Control subclase, que hace referencia al objeto sobre el que actúa VisualStateManager . La página es una Control subclase y es bastante poco frecuente que se muestre la interfaz de usuario en un contexto en el que no tenga , Pageo que la raíz Window.Content no sea una Control subclase. Se recomienda definir un UserControl personalizado para ser la Window.Content raíz o ser un contenedor para otro contenido al que desea aplicar estados (como un Panel). A continuación, puede llamar a GoToState en sus UserControl estados y aplicar independientemente de si el resto del contenido es .Control Por ejemplo, podría aplicar estados visuales a la interfaz de usuario que, de lo contrario, consta de solo un SwapChainPanel , siempre que lo coloque dentro de los UserControl estados con nombre declarados y que se apliquen a las propiedades del elemento primario UserControl o de la parte con nombre SwapChainPanel de la plantilla.

Se aplica a

Consulte también