Splitting Responsibilities with VisualStateManager

I mentioned in Creating Animation - Part 2 that I used the VisualStateManager introduced in Silverlight 2 Beta 2 to help achieve the animation of the button growing when the mouse moves over it. In this post, I want to take a closer look at the VisualStateManager and how it helps in splitting responsibilities between the designer and the developer.

One of the great aspects of WPF, Silverlight, and XAML is the ability to separate the visuals from the code and logic. This separation allows designers to work on the actual visuals of controls and applications, while developers focus on coding. One drawback to this is handling changes in the visuals based on changing conditions, such as a control receiving focus or a mouse hovering over a control. In WPF, triggers help to solve this problem; designers can alter the visuals when specific conditions are met. However, triggers do not yet exist in Silverlight.

Enter the VisualStateManager, or VSM for short. VSM handles the transition of a control between states. But, what does that actually mean? And how does it help designers and developers? Let me address the first question. The easiest way to explain states is to consider a sample control, such as a checkbox. A checkbox can be checked, unchecked, contain focus, be disabled, have a mouse hovering over it, etc. All of these are different states that the checkbox may enter. Transitions occur when a control changes states; for example, a user clicks on a checkbox to check and uncheck it. VSM drives what happens visually when a control changes states (more on this later).

For the second question, let's look at developers first. A set of states can be assigned to a user or custom control being developed by using the TemplateVisualState class attribute. The attribute defines the name of a state along with the name of a state group. States within the same state group are considered to be mutually exclusive. This allows a control to be in multiple states simultaneously. Going back to the checkbox, it makes sense to put a Checked state and an Unchecked state into the same state group. A Focused state would belong in another state group, since a checkbox can be both checked and contain focus. By defining the states and state groups for a control, the developer is telling the designer the finite number of states that the control might enter.

Using event handlers, developers can determine when a control's state has changed. For the checkbox, we could monitor the Checked and Unchecked events to know when the checkbox has changed to the Checked or Unchecked state. To actually change the state of a control, a developer would use the static method VisualStateManager.GoToState. The method takes three parameters: the control whose state is changing, the name of the state being entered, and a Boolean indicating if the state should be entered immediately or if animated transitions can occur. With full control over when a control enters a state, the developer relieves the designer from that responsibility.

For designers, Expression Blend 2.5 has incorporated using VSM into its toolkit. Using VSM is not a requirement for every Silverlight control, but it is the pattern supported by Blend. The designer can view the available states (arranged by state groups) within Blend and adjust the visuals as necessary. Blend also allows the designer to set how long a transition between two states will take. If the time is zero, the transition from state A to state B is immediate. If the transition time is greater than zero, animation will occur. However, the designer does not need to do anything to explicitly create this animation; VSM handles creating a storyboard that animates the changes from state A to state B. This can save the designer time in having to worry only about the end result and not what happens during the transition.

Note: VSM will only animate properties that change between states if a linear transition can be created. So, properties that are of type Object will not be animated. Also, the third parameter to GoToState controls whether VSM should generate animations or simply change the properties to the new state immediately.

While VSM is still in beta, I think that it is a great step forward, particularly in terms of delegating control between designers and developers. Developers of user and custom controls retain control over a control's current states while allowing designers to handle the visual aspects of those states. This does require thinking about controls and their visuals in a different manner, but, every now and then, we need to reevaluate how we accomplish certain tasks.

I realize that I did not go into any real coding or show how to actually use VSM, apart from my previous blog post. I did this on purpose, as other bloggers have put together some very good resources on using VSM. If you are interested in more details (including how to design custom transitions between states), I would highly suggest checking out Karen Corby's 4-part post on the Parts & States Model with VisualStateManager.

For anyone wondering about using VSM in desktop WPF applications, Microsoft is working on implementing support for VSM to the desktop. For a quick look at how they are progressing, John Gossman has posted a prototype of VSM for desktop WPF on his blog.

0 comments: