VisualStateManager in WPF 4.0 and MVVM


Hello everyone!

Its been a bit since I last blogged, so I wanted to give y’all some insight into the VisualStateManager in WPF 4.0 and how we can use it with the MVVM design pattern.

I’ve been looking at ways to use the VSM for things like Forms State in addition to using it for custom control development.  To set up the scenario, Imagine you have a SearchView with a SearchViewModel.  This SearchView contains an area for SearchCriteria, an area for SearchResults, and an overlay screen with a progress bar that shows the status of the search or a processing animation of some sort.  The SearchView could have a SearchStates VisualStateGroup containing states called SearchInitialized, SearchStarted and SearchCompleted.

Now in our SearchInitialized state we dont want to show the results area, the SearchStarted state we want to show the processing animation, and the SearchCompleted state we want to stop the processing animation and show the SearchResults area.  So far this makes logical sense, but lets see how the VisualStateManager can handle this.

First to setup the MVVM portion.  Were going to use the style of MVVM that injects a View into the ViewModel. (ex.  public SearchViewModel(SearchView view)).  The reason we use this is because when we work with the VSM we have to pass it a Visual that has the VisualStateGroups defined.  This already presents one limitation in the VSM, its not a terrible limitation, but it does exist.  Now we can have commands in the normal MVVM way that work with setting states.  A command handler may look like so.

   1: public void OnSearchStarted(object parameter)
   2: {
   3:     VisualStateManager.GoToState(View, "SearchStartedState", false);
   5:     //start your background process for searching here
   4:  
   6: |

Then you have a completed handler on your background process that would look like this

   1: public void OnSearchCompleted(object sender, EventArgs e)
   2: {
   3:     VisualStateManager.GoToState(View, "SearchCompletedState", false);
   4:     //handle setting the results appropriately in the ViewModel
   5: }

So you see we have a cool, abstracted way to define which state you want to go to without having to know what Visuals are in the View you are working with.  I think this is great in concept but I have found some limitations with the VSM that makes it complicated to actually use it in this way.

The biggest issue is that a VisualState object can only have an Animation defined.  This by default tells us we cant expand expanders with booleans, we cant set Visibility states, and a whole other slew of properties that we cant set.  I was able to get around the Visibility issue by creating a VisibilityAnimation.  It does nothing more than animate the Visibility property to a VisibilityState that you define in XAML in 0 seconds.  I tried creating a BooleanAnimation that does the same for expanders, but got some weird side-effects.

What we need is for the VSM to support a collection of Setters.  If we had this then we could define visual states that actually set properties on controls and reduce the requirement of an animation.  If you look at the default ControlTemplate for the Silverlight CheckBox (which uses VSM), in the CheckedState it animates the Opacity of the check mark from 0 to 1 in 0 seconds.  This to me calls into the animation API when it does not need to.

I have built a demo that shows how we can work with what we have in the VSM to accomplish this Forms visual state functionality.  You can download it here.

I hope everyone learns from this and as always have a good day!

  1. #1 by Jens on September 1, 2011 - 8:43 am

    I am really late to the party, but for any readers of this post (it ranks high on google): There is a built-in animation that can set booleans, visbilities etc: ObjectAnimationUsingKeyframes. No need to roll your own.

Comments are closed.