VisualStateManager.GoToState method

0 out of 4 rated this helpful - Rate this topic

Transitions a control between two states, by requesting a new VisualState by name.

Syntax


public static bool GoToState(
  Control control, 
  string stateName, 
  bool useTransitions
)

Parameters

control

Type: Control

The control to transition between states.

stateName

Type: System.String [.NET] | Platform::String [C++]

The state to transition to.

useTransitions

Type: System.Boolean [.NET] | Platform::Boolean [C++]

true to use a VisualTransition to transition between states. false to skip using transitions and go directly to the requested state. The default is false.

Return value

Type: System.Boolean [.NET] | Platform::Boolean [C++]

true if the control successfully transitions to the new state, or was already using that state; otherwise, false.

Remarks

When you call this method, there is expected to be a VisualState with an x:Name value that matches your stateName value, somewhere in the control template for the control identified by control. If there isn't, you don't get exceptions, but the return value will be false. The state named by stateName can be in any of the VisualStateGroup elements in the template.

VisualStateManager supports two important features for control authors, and for app developers who are applying a custom template to a control:

  • Control authors or app developers add VisualStateGroup object elements to the root element of a control template definition in XAML, using the VisualStateManager.VisualStateGroups attached property. Within a VisualStateGroup element, each VisualState represents a discrete visual state of a control. Each VisualState has a name that is representative of a UI state that can be changed by the user, or changed by control logic. A VisualState consists mainly of a Storyboard. This Storyboard targets individual dependency property values that should be applied whenever the control is in that visual state.
  • Control authors or app developers transition between these states by calling the static GoToState method of VisualStateManager. Control authors do this whenever the control logic handles events that indicate a change of state, or control logic initiates a state change by itself. It's more common for control definition code to do this rather than app code, so that all the possible visual states and their transitions and trigger conditions are there by default for app code.

When you call GoToState to change the visual state of a control, the VisualStateManager performs these actions:

  • First it's determined whether a state that matches stateName exists. If not, nothing happens and the method returns false.
  • If the VisualState as named by stateName exists, and has a Storyboard, the storyboard begins.
  • If the VisualState that the control was using from that same VisualStateGroup prior to the newly requested state has a Storyboard, that storyboard stops. Other than the specific properties that the new VisualState applies an animation to, the control reverts to the initially loaded states from the control template and its composition.

If a VisualState with an x:Name that matches stateName doesn't exist in the VisualStateGroups and ControlTemplate of the control object, GoToState doesn't change the current state of any VisualStateGroup, and returns false.

If the control is already in the VisualState requested as stateName, GoToState returns true, but there is otherwise no action (the storyboard won't be restarted).

A common control implementation pattern is to define a single private method of the control class that takes care of all possible VisualState changes for the control. Which visual state to use is determined by checking the control's properties, which might be public or private. Those properties are adjusted by control event handlers for events such as OnGotFocus and are checked just-in-time immediately before setting the visual state. The example below uses this implementation pattern. Alternatively, you can call GoToState for individual states from within event handlers, from control event handler overrides (the On* methods), or from helper methods that are called by all possible impetus for changing states (user-driven events, automation events, initialization logic).

You might also call GoToState from within the PropertyChangedCallback implementation for a custom dependency property.

Visual states and transitions

In addition to the visual states, the visual state model also includes transitions. Transitions are animation actions controlled by a Storyboard that occur between each visual state when the state is changed. The transition can be defined differently for each combination of starting state and ending state as defined by your control's set of visual states. Transitions are defined by the Transitions property of VisualStateGroup and are usually defined in XAML. Most default control templates don't define transitions, and in this case the transitions between states happen instantaneously. For more info, see VisualTransition.

A VisualTransition can also be defined such that it produces an implicit transition. Any dependency property that is specifically targeted for animation in either the From orTo visual states of a VisualTransition and has different values across the state change can be animated with an implicit transition animation. This generated animation transitions between the From state value and the To state value of such a property using interpolation. The implicit transition animation lasts for the time stated by the GeneratedDuration value of a VisualTransition. Implicit transitions only apply to properties that are a Double, Color or Point value. In other words the property must be possible to implicitly animate using a DoubleAnimation, PointAnimation or ColorAnimation. For more info, see GeneratedDuration.

Events for visual state changes

CurrentStateChanging fires when the control begins to transition states as requested by the GoToState call. If a VisualTransition is applied to the state change, this event occurs when the transition begins.

CurrentStateChanged fires after the control is in the state as requested by the GoToState call, just as the new Storyboard begins. No event is fired on the new storyboard's completion.

If a VisualTransition is not applied, CurrentStateChanging and CurrentStateChanged fire in quick succession, but are guaranteed in that order if both occur.

However, if a state change transition is interrupted by a new GoToState call, the CurrentStateChanged event is never raised for the first state transition. A new event series is fired for the next requested state change.

OnApplyTemplate is not invoked for visual state changes. OnApplyTemplate is only invoked for the initial load of a control into a XAML UI.

Attributing a custom control's named visual states

If you are defining a custom control that has visual states in its control template XAML, it's a best practice to attribute the control class to indicate to control consumers which visual states are available. To do this, apply one or more TemplateVisualState attributes at the class level of your control definition code. Each attribute should specify the state's x:Name, which is the stateName value a control consumer would pass in a GoToState call to use that visual state. If the VisualState is part of a VisualStateGroup, that should also be indicated in the attribute definition.

A related concept is that control authors should attribute the names of key control parts using TemplatePartAttribute. This is very helpful if control consumers want to access named parts from the template scope after the template is applied. TemplateVisualStateAttribute and TemplatePartAttribute combined help define the control contract for a control.

Custom VisualStateManager

As an advanced scenario, it is possible to derive from VisualStateManager and change the default GoToState behavior. The derived class should override the protected GoToStateCore method. Any instance of the custom VisualStateManager uses this Core logic when its GoToState method is called.

Examples

This example demonstrates control logic that uses the GoToState method to transition between states.


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

}


Here's what the XAML that declares the visual states for the control looks like:


<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>


Requirements

Minimum supported client

Windows 8

Minimum supported server

Windows Server 2012

Namespace

Windows.UI.Xaml
Windows::UI::Xaml [C++]

Metadata

Windows.winmd

See also

VisualStateManager
Quickstart: Control templates
GoToStateCore
x:Name
TemplateVisualStateAttribute
VisualStateGroup
VisualState

 

 

Build date: 1/31/2013

Did you find this helpful?
(1500 characters remaining)
© 2013 Microsoft. All rights reserved.