Bogdan Bujdea

Windows Platform Developer

Windows Phone TDD Part 2: Working with Caliburn.Micro

The only MVVM libraries that I tried until now are MVVM Light and Caliburn.Micro. Although I think the first one is really good, I don’t like that I have to put stuff like Commands in my ViewModel, and it takes time to create behaviors for every event you want to subscribe. That’s why I prefer Caliburn.Micro

If you haven’t heard about it until now

Caliburn.Micro is a small, yet powerful framework, designed for building applications across all XAML platforms. With strong support for MVVM and other proven UI patterns, Caliburn.Micro will enable you to build your solution quickly, without the need to sacrifice code quality or testability.

It keeps my ViewModel very clean, so this means it’s easy to test. Another reason is that I don’t need commands and behaviours, all the binding is done in the XAML files. For more info you should go on their codeplex page or view the tutorials made by Matteo Pagani about Windows Phone 8 apps with Caliburn.

Now let’s start working. The first step is to create the solution for my project. You probably start by creating a Windows Phone project, but I will create an empty solution. This is because I will add more projects, and I want every project to have a name for it’s function, so the WP8 project name will end in .WP8, the tests project name will end in .Tests, and the PCL project will end in .PCL or .PortableLogic…it doesn’t really matter, but it’s good to give them descriptive names. Here’s a screenshot:

VS Empty Solution

VS Empty Solution

The next step is to create the Windows Phone 8 project. As I said earlier, it will be named BudgetPlanner.WP8

Windows Phone 8 New Project

Windows Phone 8 New Project

Now we have to add Caliburn.Micro.  You can find Caliburn.Micro on Nuget. When you search for it, you will also find “Caliburn.Micro.Start”, which is the package you should install. The difference between “Caliburn.Micro.Start” and “Caliburn.Micro” is that the first one creates some files for you and it makes the configuration part easier.

Caliburn Micro Nuget

Caliburn Micro Nuget

After the installation is complete, you will see this page opened in Visual Studio. It shows you how to add Caliburn.Micro to your project. Basically, these are the steps:

  1. Add the AppBoostrapper class as a resource in the App.xaml file. Here’s how my App.xaml looks like
  2. Delete the unnecessary code from the App.xaml.cs file. Here’s a gist with my file
  3. Create the /Views and /ViewModels folders in the root of your project. This is how Caliburn knows where to find your views and view models.
  4. Add a view in the /Views folder. You can move the existing MainPage or create a new one, but the file has to end with “View”. So you can have LoginView and LoginViewModel, MainView and MainViewModel, etc…you get the point. I like to keep this convention, but Caliburn is configurable so you can change it at any time.
  5. Add a ViewModel in the /ViewModels folder and make sure you add it in the AppBoostrapper like this:
    _container<span style="color: #b4b4b4;">.</span>PerRequest<span style="color: #b4b4b4;">&lt;</span><span style="color: #4ec9b0;">MainViewModel</span><span style="color: #b4b4b4;">&gt;</span>();

    You should see this line in your AppBootstrapper, but keep in mind that you have to do this for every new ViewModel that you add. Caliburn already created a MainViewModel.cs file and placed it in the root of your folder, so now you can move it to the /ViewModels folder instead of creating a new one.

  6. Change the Navigation Page from your WMAppManifest.xml to point to /Views/MainView.xaml

Here’s how my project looks like now:

caliburn-installed

caliburn installed

Now I’m ready to see if it worked. To do this, I will bind the name of the page to a property from the ViewModel. In the MainView.xaml I will add a name to the TextBlock that has my page name:

<span style="color: gray;">&lt;</span><span style="color: #e6e6e6;">TextBlock</span><span style="color: #92caf4;"> x</span><span style="color: gray;">:</span><span style="color: #92caf4;">Name</span><span style="color: gray;">=</span><span style="color: #569cd6;">"PageName"</span> <span style="color: #92caf4;"> </span><span style="color: #92caf4;">Style</span><span style="color: gray;">="{</span><span style="color: #bba08c;">StaticResource</span><span style="color: #d7ba7d;"> PhoneTextTitle1Style</span><span style="color: gray;">}</span><span style="color: #569cd6;">"</span><span style="color: gray;">/&gt;</span>

In the MainViewModel class we will add a property with the same name as the TextBlock that has the page title. By giving them the same name, Caliburn will know to bind the property to the TextBlock.

<span style="color: #569cd6;">public</span> <span style="color: #569cd6;">string</span> PageName { <span style="color: #569cd6;">get</span>; <span style="color: #569cd6;">set</span>; }

In the constructor of MainViewModel we will set the PageName to the title we want. Demo

If you run the project, you should see that the page title has changed. I changed it to “It worked!”

MainViewModel

MainViewModel

And here’s how my MainView.xaml.cs looks like:

<span style="color: #569cd6;">namespace</span> BudgetPlanner<span style="color: #b4b4b4;">.</span>WP8<span style="color: #b4b4b4;">.</span>Views
{
    <span style="color: #569cd6;">public</span> <span style="color: #569cd6;">partial</span> <span style="color: #569cd6;">class</span> <span style="color: #4ec9b0;">MainView</span>
    {
        <span style="color: #569cd6;">public</span> MainView()
        {
            InitializeComponent();
        }
    }
}

It’s clean, it doesn’t have any code besides the constructor which initializes the UI. That’s how the code of the view should look like. In some cases, you will have to add code here, but only code that it’s related with the user interface, the logic stays in the ViewModel.

That’s it for now. You can watch and download the project from here: https://bitbucket.org/bogdanbujdea/moneyplanner. The next step will be to create our project for the unit tests, and we will write our first test using NUnit.

TDD posts series:

, , ,