VisualStateManager.GoToState(Control, String, Boolean) Método
Definición
Importante
Parte de la información hace referencia a la versión preliminar del producto, que puede haberse modificado sustancialmente antes de lanzar la versión definitiva. Microsoft no otorga ninguna garantía, explícita o implícita, con respecto a la información proporcionada aquí.
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 para realizar la transición entre estados.
- stateName
-
String
Platform::String
winrt::hstring
Estado al que se va a realizar la transición.
- useTransitions
-
Boolean
bool
true para usar 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
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 cambios en el tamaño o la orientación de la ventana de la aplicación).
Cuando se llama a este método, se espera que sea 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 se obtienen excepciones, pero el valor devuelto será false. El estado denominado por stateName puede estar en cualquiera de los elementos De VisualStateGroup de la plantilla para el control especificado. Es necesario realizar un seguimiento de los estados en los que VisualStateGroup 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 se define 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 desarrolladores de aplicaciones que aplican una plantilla personalizada a un control:
- Los autores de controles o los 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.VisualStateGroupspropiedad adjunta. Dentro de unVisualStateGroupelemento, cada Objeto VisualState representa un estado visual discreto de un control. CadaVisualStatetiene un nombre que es representativo de un estado de interfaz de usuario que el usuario puede cambiar o cambiar por lógica de control. UnVisualStateconsta principalmente de un guión gráfico. EstoStoryboardtiene 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 los 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 los 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 lo haga 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 al 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 devuelvefalse. - Si el objeto VisualState tal como lo denomina
stateNameexiste y tiene un guión gráfico, comienza el guión gráfico. - Si el objeto VisualState que el control usaba desde ese mismo Objeto 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
VisualStateaplica 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 el objeto 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 realiza transiciones 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 los estados según lo solicitado por la GoToState llamada. Si se aplica 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 estado según lo 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 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 los cambios de estado visual. OnApplyTemplate solo se invoca para la carga inicial de un control en una interfaz de usuario XAML.
Atribuyendo estados visuales denominados de un control personalizado
Si vas a definir un control personalizado que tenga estados visuales en su XAML de plantilla de control, es recomendable 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 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 resulta muy útil si los consumidores de control quieren acceder a elementos con nombre desde el ámbito de 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 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 configurar esto, debe definir la plantilla de control y los estados visuales 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 la composición básica solo. 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
A veces, los estados visuales son útiles para escenarios en los que desea cambiar el estado de alguna á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 una Pageraíz Window.Content o que la raíz Window.Content no sea una Control subclase. Se recomienda definir un UserControl personalizado para que sea la Window.Content raíz o ser un contenedor para otro contenido al que quiera aplicar estados (como un Panel). A continuación, puede llamar GoToState a en los 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, consiste solo en un SwapChainPanel siempre y cuando lo coloque dentro de los UserControl estados con nombre declarados que se aplican a las propiedades del elemento primario UserControl o de la parte con nombre SwapChainPanel de la plantilla.