Binary Bob’s Blog

23
Sep

Animations and View State changes with MVVM

Posted By Bob Bartholomay under Silverlight.

A recent question on the Silverlight forums reminded me of an issue any MVVM fanboy will face sooner or later: “Is it possible to start an animation (StoryBoard in the XAML) from the ViewModel”?

One of the major tenets of MVVM is “separation of concerns” in that the View is not supposed to know about the ViewModel (among other things). The View’s DataContext gets set on its instantiation and from there on out all it knows is that parts of it are databound to something somewhere.

Animations/Storyboards happen in the View. For example, the transition from one ViewState to Another. So how do you get a StoryBoard to begin or cause ViewState change when a Property in the ViewModel changes or is of a particular value? The poster wanted a MVVM solution that follows the mantra: “no (read little as possible) code behind for the View”.

I’ve solved this previously by using Routed Events fired from the ViewModel in response to a Command associated with a UI Control. What I hadn’t solved was how to get these View changes purely on changes to the data in the ViewModel.

I scoured the Web and found more questions than solutions but eventually identified a number of approaches (some better than others):

  1. ICommands and RoutedEvent
  2. Using an IView interface
  3. ICommand and CLR Events
  4. Using a StoryboardManager
  5. Using DataTriggers

ICommands and RoutedEvent: It goes like this: a ButtonBase has an ICommand associated with it. The Command handler in the VM sets a Property ( that implements INotifyPropertyChanged) in the ViewModel and Raises a RoutedEvent that’s listened for and handled in the View where it changes State or starts a Storyboard. This has some (little) code behind in the View.

Using an IView interface: All the Views in the app implement an interface that dictates a method implementation be specified that allows the ViewModel to “mess with” the View (via the implemented method) like changing a ViewState. Here the ViewModel knows too much about the View and “calls into it”.

ICommand and CLR Events: basically the same scenario as with RoutedEvents but should be used if all you need is the CLR event functionality.

Using a StoryboardManager: this is the solution the forum poster found and used. Its a solution created by Chris Klug which honors the separation between the View and VM by using an Attached Property. You can read about it on his blog ( link above) or see it in the example code below.

Using DataTriggers: Did I getcha? Silverlight doesn’t have a DataTrigger implementation but Peter Blois’ (again he solves the big issues!) worked one up and it solves the problem perfectly. Great separation, can be used in Blend and follows the DataTrigger XAML syntax that WPF uses.

I wrote a test app that implements all the above except the IView Interface. You can play with the app below but you’ll need to look at the code and the links referenced to get a good idea of how they work and which is best for you and your particular project.

One thing’s for sure. When there’s a “Silverlight vacuum”, sharp devs fill it quickly with elegant solutions and best of all they take the time to blog their ideas and share with the Silverlight community. – Cheers!

Visual Studio Solution download

References:

9 Responses to “Animations and View State changes with MVVM”

  1. Links (9/24/2009) « Steve Pietrek – Everything SharePoint said:

    [...] Animations and View State changes with MVVM [...]

  2. James Ashley said:

    Bob,

    I like your solution. I don’t think it is the case that the View knows nothing about the view-model, however. It actually has to know a lot about the fields provided on the view-model and the structure of the vm (or, conversely, the v-m has to know a lot about the view). In other words, they are fairly tightly coupled.

    Where it helps in SOC is that we take presentation logic that would otherwise be in the view and separate it out into its own class. Concerns such as presentation logic and state are separated out into the vm, while the view is concerned with data presentation, colors, layout and animations.

    At least that’s my take on it.

    -James

  3. Bob Bartholomay said:

    Thanks for your thoughtful comments James. Semantics get in the way sometimes but I think we all agree about the separation between the View and VM being important and that Commanding is the ticket for communication between them. There’s a very interesting discussion on MVVM in the Silverlight forums that you’ll probably enjoy. – bob

  4. Tweets that mention Binary Bob’s Blog » Animations and View State changes with MVVM -- Topsy.com said:

    [...] This post was mentioned on Twitter by SilverlightDC and codenenterp. codenenterp said: RT @brian_henderson: RT @brandontruong: Binary Bob’s Blog » Animations and View State changes with MVVM http://blog.flexforcefive.com/?p=206 [...]

  5. Jeremy Likness said:

    I addressed the issue in a similar way, but by eliminating participating by the view model. It’s a little different scenario: I wanted to trigger animations based on UI events such as selection changing. The solution is posted here:

    http://csharperimage.jeremylikness.com/2009/10/silverlight-behaviors-and-triggers.html

  6. Rishi said:

    My take on this problem is a very simple, basically data changes are your signifiers that effect changes in the View from your ViewModel. And to this concept, I’ve written something similar to Peter Blois’s DataTriggers but they are more generalized in a sense that they allow you to use operators using Blend triggers such as ==, >=, <=, ==null etc. and match that with any trigger-action you want including one to manage animations.

    See http://www.orktane.com/Blog/post/2009/09/29/Introducing-nRouteToolkit-for-Silverlight-(Part-I).aspx

    Cheers

  7. Chris Klug said:

    Hi Bob!
    Thanks for mentioning my blog post about MVVM and animations. Would be cool if you could change my name from Chris North to Chris Klug though…since that is my name… :)
    Cheers!

  8. Chris Klug said:

    BTW…I should probably add my 2 cents as well… I do agree with James that on of the end has to know a lot about the other. In my mind the ViewModel should be adapting the model and make it usable for the view. This can involve adding or modifying information from the view as well as add functionality. The reason for having a CommandManager for Silverlight was that there was no pre-made implementation available, and most of the ones I found were based on ButtonBase. In SL4, ButtonBase will have commanding support ond make the CommandManager somewhat useless, but on the other hand, only having commanding support on ButtonBase and not for all events is kind of limiting in my mind.
    Rishi’s nRoute looks great for a lot of things, but a lot of my projects it is too heavy and too powerfull for what I need. And I don’t really need the blendability in most situations…
    But that’s just my 2 cents…
    Cheers…again…

  9. Bob Bartholomay said:

    Chris Klug! A thousand apologies for renaming you (you’ve been refactored!), thanks for bringing that to my attention as well as for the StoryboardManager irself. The post has been corrected. – bob

Leave a Reply