Part 1: Manage Page level states with VisualStateManager in Silverlight

Silverlight 2.0 Beta 2 introduced the concept of Visual State Manager (VSM). If you haven't checked it out still, here are some articles that will get you started.

VSM not only helps keep the looks and behavior of a control separate, it allows you to manage the various states the control can be in, along with the transitions, in a very clean and effective manner. Though most of the examples online today show this in context of a specific control and working with its control template, there is no reason why this can't be applied to the UserControl itself, i.e. at the Page level. You can very easily create custom states for your page and manage transitions between the states. In fact this can actually help reduce the total animations that you may have to write and also simplify the backend code.

In this two part blog post, I will explain this with a small sample. I am assuming basic understanding of Silverlight animations and VSM as well. In this first part I will explore how you would build an application without VSM and in part 2, create a similar experience but with using VSM.

Let's start with taking a simplistic case where we will have 3 buttons on my Page which act like menu control. On clicking a particular button, it will animate downwards, thus showing the active button. We will assume that the rest of the page has content filled up based on which button was clicked. To start with the here's the XAML with 3 buttons in a Grid.

Next is to add the required animation so that a button can move to the new location. For this we can use Blend and add Button1Animation, which moves the button down. We use the TranslateTransform property and modify the Y value to 40. The animation storyboard is as below.

While this animation moves the button down, we will need another animation to move the button back to its original position when another button is moved down. To do this, Blend offers an easy way by which we can create a duplicate animation and then reverse it from the Objects and Timeline panel. See the figure below.

The next step is to stitch this together so that when we click a button, it moves down and the one already down moves back to its original position. For this the code will be something like below.

publicpartialclassPage : UserControl

{

enumMenuButton

{

None,

One,

Two,

Three

}

MenuButton _current;

public Page()

{

InitializeComponent();

_current = MenuButton.None;

}

privatevoid btn1_Click(object sender, RoutedEventArgs e)

{

//if the current button is different than the one clicked, animate it back and then animate this button in

if (_current != MenuButton.One)

{

AnimateOut(_current);

Button1Animation.Begin();

_current = MenuButton.One;

}

}

privatevoid btn2_Click(object sender, RoutedEventArgs e)

{

//if the current button is different than the one clicked, animate it back and then animate this button in

if (_current != MenuButton.Two)

{

AnimateOut(_current);

Button2Animation.Begin();

_current = MenuButton.Two;

}

}

privatevoid btn3_Click(object sender, RoutedEventArgs e)

{

//if the current button is different than the one clicked, animate it back and then animate this button in

if (_current != MenuButton.Three)

{

AnimateOut(_current);

Button3Animation.Begin();

_current = MenuButton.Three;

}

}

//animate the button back to its original location

privatevoid AnimateOut(MenuButton btn)

{

switch (btn)

{

caseMenuButton.One:

Button1Animation_Copy.Begin();

break;

caseMenuButton.Two:

Button2Animation_Copy.Begin();

break;

caseMenuButton.Three:

Button3Animation_Copy.Begin();

break;

}

}

}

If you run the application now and click any button, you will see it animate down and the previous button will animate and move back. This concludes part 1. In part 2 we will look at how using VSM, we can simplify this application and reduce the amount of code we have to write.