You are reading an old version of my weblog. Please update your bookmarks to http://www.timmykokke.com
Intro
Visual States are an easy way to change the looks of your controls based on certain states. This state can be something like a mouse hover, some invalid state or any state you need in a control.
For this tutorial I chose a traffic light control that can be one of four states. Green, Orange, Red and Inconclusive (blinking orange). In the end I show you how to use behaviors on buttons to set the state of the traffic light. This makes the use of visual states perfectly suitable for use in MVVM projects.
Part 1 – Setting up the project
Start by creating a new Silverlight project in Visual Studio 2010 and add a new Item to the project by right clicking on the project in the Solution window and click Add –> New Item… or hit Ctrl+Shift+A.

Select the Silverlight Templated Control item template from the list of Silverlight templates

Add a folder named Themes to the Silverlight project. Add a ResourceDictionary to the project by using the Add->New Item… on the project folder and name this dictionary Generic.xaml. Add the following style to the dictionary:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:VsmDemo="clr-namespace:VsmDemo">
<Style TargetType="VsmDemo:TrafficLight">
<Style.Setters>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate/>
</Setter.Value>
</Setter>
</Style.Setters>
</Style>
</ResourceDictionary>
Add a reference to the dictionary in App.xaml:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Themes/generic.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
Build the solution to see I there aren’t any mistakes so far.
Part 2 – Drawing in Blend
Start Expression Blend and load the solution.
The template is still empty. To start editing the style for the TrafficLight control, go to the Resource pane, look for the generic.xaml entry, open it and click on the button on the right of the style entry.

To edit the template in the style, right click the style in the Objects and Timeline pane and select Edit Template –> Edit Current.

Now draw a traffic light like this.

If you don’t like/want/know how to draw the light, just copy-past the xaml below into the xaml editor. It’s basically just a border with a grid containing three ellipses.
<ControlTemplate>
<Border d:DesignHeight="200.00" BorderBrush="#FFCACACA"
BorderThickness="3"
Background="#FF333333" CornerRadius="40"
d:DesignWidth="110">
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30"/>
<ColumnDefinition/>
<ColumnDefinition Width="30"/>
</Grid.ColumnDefinitions>
<Ellipse x:Name="GreenLight"
Grid.Column="1" Grid.Row="1"
Fill="Black" Margin="2"
Stretch="Uniform"/>
<Ellipse x:Name="OrangeLight"
Grid.Column="1" Grid.Row="2"
Fill="Black" Margin="2"
Stretch="Uniform"/>
<Ellipse x:Name="RedLight"
Grid.Column="1" Grid.Row="3"
Fill="Black" Margin="2"
Stretch="Uniform"/>
</Grid>
</Border>
</ControlTemplate>
Instantly the traffic light should show up in the designer.
Time to save your work again. Switch back to Visual Studio, and reload the files if you’re asked to.
Part 3 – Code… Finally
The selection of the different states will be based on an enum. Add a new enum to the Silverlight project.
public enum TrafficLightStates
{
Inconclusive = 0,
Green = 1,
Orange = 2,
Red = 3
}
The state of the traffic light will be stored in the control in a dependency property. The property will be set to TrafficLightStates.Green by default. A method must be called when the property changes to notify the state manager to change the state of the traffic light.
public TrafficLightStates State
{
get { return (TrafficLightStates)GetValue(StateProperty); }
set { SetValue(StateProperty, value); }
}
public static readonly DependencyProperty StateProperty =
DependencyProperty.Register(
"State",
typeof(TrafficLightStates),
typeof(TrafficLight),
new PropertyMetadata(TrafficLightStates.Green,
OnLightStateChanged)
);
To get the code to build, add a basic implementation of the OnLightStateChanged method. The OnLightStateChanged method calls the non-static SetState method. This way there will be only one method in which the visual state will be changed. The SetState method is empty for now.
private static void OnLightStateChanged(DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
((TrafficLight)d).SetState();
}
private void SetState(){}
To make the four different visual states known to the application you’ll have to use the TemplateVisualState attribute. This attribute takes the name of the state and the name of the group the visual state belongs to. Add an instance of the TemplateVisualState attribute for each of the four states to the TrafficLight class.
[TemplateVisualState(Name = "Green",
GroupName = "TrafficLightStates")]
[TemplateVisualState(Name = "Orange",
GroupName = "TrafficLightStates")]
[TemplateVisualState(Name = "Red",
GroupName = "TrafficLightStates")]
[TemplateVisualState(Name = "Inconclusive",
GroupName = "TrafficLightStates")]
Now the states are named it is time to set the visual states based on the state of the traffic light. This is done by a simple switch block in the SetState method.
Changing the visual state of a control is done though a static method on the VisualStateManager class. Calling the GotoState method with the name will change the current visual state to a new one. Any transitions will be played automatically, if the useTransitions parameter is set to true. The GotoState method also needs a control of which the visual state needs to be sit. For this example we can just pass this to the method.
private void SetState()
{
switch (State)
{
case TrafficLightStates.Green:
VisualStateManager.GoToState(this, "Green", true);
break;
case TrafficLightStates.Orange:
VisualStateManager.GoToState(this, "Orange", true);
break;
case TrafficLightStates.Red:
VisualStateManager.GoToState(this, "Red", true);
break;
default:
VisualStateManager.GoToState(this, "Inconclusive", true);
break;
}
}
The last thing that has to be done in code is setting the initial state by calling the SetState method once. You can override the OnApplyTemplate method for that.
public override void OnApplyTemplate()
{
SetState();
base.OnApplyTemplate();
}
Build to see if there are any mistakes made in the code… After that, switch back to Expression Blend.
Part 4 – Visual States
The last part of this tutorial will take place in Expression Blend. Every state of the traffic light has to have a corresponding visual state. The green light must be green, etc.
Go to the template of the TrafficLight control as shown before and open the States pane. Click on the Add State Group button on the right side of the pane.

Rename the VisualStateGroup group to TrafficLightStates.

Add four states to the group by clicking the Add state button right of the TrafficLightStates group header four times.


Rename the states to Green, Orange, Red and Inconclusive.

With the Green visual state and the GreenLight Ellipse selected, change the fill of the ellipse to green, like #FF2AFF00. Notice the red border around the drawing area indicating changes to the properties will be recorded. A small red light with a caption is shown at the top of the drawing area letting you know which state is recorded too, in this case “Green state recording is on”
This process needs to be repeated for the orange and red ellipses too. In the example I’ve used #FFFFAA00 for the orange ellipse and #FFFF0000 for the red one.
The last state, Inconclusive, needs an animation so the orange light blinks. Select the Inconclusive visual state on the States pane. Show the animation timeline by clicking on the Show Timeline button on the Objects and Timeline pane.

Move the time slider to 0,5 seconds. Change the color to Orange (#FFFFAA00). Move the time slider to 1 second and change the color to black.
Click on the first key frame and set its easing function to cubic out.

Repeat the same for the second key frame. Set its easing function to cubic out also.
Select the storyboard by clicking on Inconclusive in the Objects and Timeline pane.

In the properties pane, set the Repeat Behavior of the storyboard to Forever.

That’s it for the visual states. Try compiling the application.
Part 5 – Testing the control
Open MainPage.xaml in Expression Blend.
Add the TrafficLight control to the LayoutRoot grid and give it a width of 110 and a height of 200.
To navigate to the four different states of the traffic light, add four buttons to the LayoutRoot grid and set their content to Green, Orange, Red and Inconclusive. Like this:

To change to State property of the traffic light you can use a ChangePropertyAction. You can find this in the Behaviors group on the Assets pane.

Drag-‘n-drop this action on the first button.

Select the Action in the Objects and Timeline pane. To set the TargetObject of action to the traffic light just click on the Artboard element picker and than on the traffic light.

Select State from the PropertyName combobox.

Select Green from the Value combobox.

Repeat the same process for the other three buttons. You can clone the behavior from element to element by selecting the behavior and drag-‘n-drop it to another element while holding down the Ctrl key.
Done!
Hit F5 to admire your work
You can download the source of the project here.
If you run into any issues or if you have comments or questions, please let me know. To be the first to know if there’s a new post on my blog, please subscribe to the RSS feed or follow me (@sorskoot) on twitter.