Normally you want to make animations using storyboards and then some code behind to start the animations. In this post I’ll show you a way to implement the animation in a very clean and MVVM way on a very simple application.

The Sample Application

The application is quite simple - it’s a compass app… well kinda… when you press one of the buttons, the arrow will point towards that button/direction:

Sample application

In the following sections I’ll detail how to use enums to switch between the states.

Visual State Manager in Microsoft Blend

First, you create the states for each cardinal point, then you select one of the states and the blockArrow from Objects and Timeline, then go to Properties and change the Angle for that state. Repeat for all states. Check the screenshot below for more details.

Visual State Manager in Microsoft Blend

The Switch Buttons

This is the enum that everything is based on:

public enum CardinalPoint
{
    North, East, South, West
}

The next most important thing is the command that switches between these states. Basically the command does nothing more than take an enum as parameter and set it on the view model:

public class SwitchCommand : ICommand
{
    private readonly MainViewModel _viewModel;

    public SwitchCommand(MainViewModel viewModel) =>
        _viewModel = viewModel;

    public void Execute(object parameter) =>
        _viewModel.CardinalPoint = (CardinalPoint)parameter;

    // other unimportant code
}

And this is how the CommandParameter is used to provide the enum to the command:

<Button Content="North"
        Command="{Binding SwitchCommand}"
        CommandParameter="{x:Static local:CardinalPoint.North}" />

Of course, we shouldn’t forget to declare the command in the view model, like this:

public class MainViewModel : INotifyPropertyChanged
{
    public ICommand SwitchCommand { get; set; }

    public MainViewModel()
    {
        SwitchCommand = new SwitchCommand(this);
    }

    private CardinalPoint cardinalPoint;
    public CardinalPoint CardinalPoint
    {
        get { return cardinalPoint; }
        set
        {
            cardinalPoint = value;
            OnPropertyChanged();
        }
    }

    // other unimportant code
}

And finally, we’re going to use Blend Behaviors to bind everything together:

<i:Interaction.Triggers>
    <ei:PropertyChangedTrigger Binding="{Binding CardinalPoint}">
        <ei:GoToStateAction StateName="{Binding CardinalPoint}" />
    </ei:PropertyChangedTrigger>
</i:Interaction.Triggers>

Whenever the CardinalPoint property will change, the PropertyChangeTrigger will, well, trigger and will execute the GoToStateAction that will start the animation corresponding to the state provided. Here we can use a binding to the CardinalPoint property (which is an enum), BUT we just need to be careful so the animation states have exactly the same names as the enum.

More explanations

This approach seems quite good because we can control the animations using just some bindings to an enum which makes it very clean and easy to test. There is no extra code behind for handling the animations, just pure bindings to enums and using commands and blend behaviors.

Unit Tests

Hmm… every time I read something about MVVM and something being easy to test the tests are missing for some reason… I plan to change that… Here are the tests proving that this approach is easy to test. I used NUnit v3 and made the tests respect the standard pattern: Arrange, Act, Assert. Here they are:

using BlendAnimationsVisualStateBinding;
using NUnit.Framework;

namespace Tests
{
    [TestFixture]
    public class MainViewModelTests
    {
        [TestCase(CardinalPoint.North)]
        [TestCase(CardinalPoint.East)]
        [TestCase(CardinalPoint.South)]
        [TestCase(CardinalPoint.West)]
        public void CardinalPointIsUpdatedWhenCommandIsInvokedWith(CardinalPoint cardinalPoint)
        {
            var viewModel = new MainViewModel();

            viewModel.SwitchCommand.Execute(cardinalPoint);

            Assert.That(viewModel.CardinalPoint, Is.EqualTo(cardinalPoint));
        }
    }
}

And here’s how they look in the Test Explorer:

Test Explorer with unit tests

Of course, there could be more to test, for example: do the animations actually work? The property is set, but is the binding correctly done in the view? For that you’d have to rely on visual/manual testing… or you could spend some effort on trying to automate that… but I’m not sure if this has a good return on investment… The visual part is the easiest to identify when something is broken - it pops right into your eyes. Anyway, this is for you to decide on a case by case basis… At least the most important stuff: the view model is tested!

Full Example Source Code

Hopefully this will help you in replicating the behavior I demoed here. To make it easier I published the full source code on GitHub so you can run it on your own computer.