Category Archives: MVVM

Managing WP7 UI state with Caliburn.Micro’s guard conditions

My first Windows Phone 7 app had a lot of extraneous code whose sole purpose was enabling and disabling pieces of the user interface. Managing the visual state of buttons was one pain point. I ended up with a lot of code that looked like this:

private void ToggleButtons()
{
    if (timer.Status == "running")
    {
        StartButton.IsEnabled = false;
        EndButton.IsEnabled = true;
    }

    else if (timer.Status == "stopped")
    {
        StartButton.IsEnabled = true;
        EndButton.IsEnabled = false;
    }
}

There are about 20 things wrong with that example, but the one I’d like to focus on is how poorly conditional checks like this scale. It’s manageable when I have two buttons, but what if I had 10? Add in a third status code and the code balloons to dozens or even hundreds of lines in a hurry. (While this article focuses on MVVM, if you want to reimplement that example more elegantly in a traditional codebehind style, leave a comment. I’d be interested to see what you come up with.)

The Caliburn.Micro MVVM framework provides an elegant means for handling this scenario. Rather than setting a button’s enabled state manually, Caliburn.Micro allows you to create a boolean property that indicates whether a button can perform its intended function. If the button’s operation can’t successfully execute, the button itself is automatically disabled. Let’s look at a simple example.

Overview of the sample

The sample app illustrates how to implement a common scenario:

  • MainPage.xaml includes a textbox, a textblock and a button.
  • As long as the textbox is empty, the publish button is disabled.
  • When the user enters text in the textbox, the publish button is automatically enabled.
  • Clicking the publish button displays the entered text in the textblock

Dead-simple databinding

Here’s the entire view, minus some boilerplate and formatting attributes:

<Grid x:Name="LayoutRoot">
    <Grid x:Name="ContentGrid">
        <StackPanel >
            <TextBlock Name="PublishedText"/>
            <TextBox Name="TextToPublish" />
            <Button Content="Publish"
                    Name="Publish" />
        </StackPanel>
    </Grid>
</Grid>

I’m using Caliburn.Micro’s convention-based databinding to link the three elements in my UI to properties in the page’s viewmodel. In this case, it’s simply a matter of applying a Name attribute to each element that corresponds to a property or method name in the viewmodel. Caliburn.Micro wires them up automatically.

Properties, action messages and guards

The heavy lifting, such as it is, happens in the viewmodel:

public class MainPageViewModel : PropertyChangedBase
{
    private  string textToPublish;
    public string TextToPublish
    {
        get
        {
            return textToPublish;
        }
        set
        {
            textToPublish = value;
            NotifyOfPropertyChange(() => CanPublish);
        }
    }

    public bool CanPublish 
    { 
        get
        {
            if (string.IsNullOrEmpty(TextToPublish))
                return false;
            else
                return true;
        }
        
    }
    
    public string PublishedText { get; set; }

    public void Publish()
    {
        PublishedText = TextToPublish;
        NotifyOfPropertyChange(() => PublishedText);
    }
}

There are several key elements to this viewmodel. First, note that MainPageViewModel inherits from PropertyChangedBase, which is Caliburn.Micro’s base class implementation of INotifyPropertyChanged. The NotifyOfPropertyChange method is defined in PropertyChangedBase. Which brings me to the second important element…

The NofityOfPropertyChange calls are what tell the view that something has changed and trigger it to update itself. In this case, the TextToPublish property is updated automatically when the user enters text into the databound TextToPublish textbox. The property’s setter then pokes the view and tells it to reevaluate CanPublish.

CanPublish is what is known as a CanExecute guard condition. A guard condition is a boolean property that is paired via a naming condition to a method in the viewmodel. If the guard returns false, it blocks the method from executing, and the corresponding UI element is disabled until the CanExecute condition evaluates to true.

To implement a guard, create a boolean property and append the word Can to the beginning of the method name that the guard is associated with. In the example, CanPublish is guarding the Publish method, which is linked to the Publish button in the view.

TextToPublish kicks the view to check CanPublish, which evaluates whether any text exists in TextToPublish. If the property contains text, CanPublish returns true, and the publish button lights up to let the user know that the button is enabled.

Download the sample

A complete Visual Studio project that implements the example above is available at my Codeplex site. It was built with the February 2011 version of the Window Phone Developer tools. Other than the WP7 tools, there are no external dependencies. The Caliburn.Micro framework code is included in the Framework folder.

Leave a comment

Filed under Caliburn.Micro, MVVM, Windows Phone 7

Introduction to messaging with Caliburn.Micro’s EventAggregator

It started innocently enough. I wanted to make the phone vibrate when a countdown timer in my app reached 00:00:00. Hmmmm… What to do… I know, I’ll add an event to the Timer object and fire it at the appropriate time. Then I can create an event handler in my viewmodel and trigger the vibration.

But when I decided to add two more events to the CountdownTimer class, things started to spin out of control. Suddenly I found myself pounding out helper methods and attaching and detatching event handlers in my viewmodel and checking conditions to see which ones should be attached when… Finally my app got to the point where it was just permanently stuck at a breakpoint as some attached event somewhere fired repeatedly, ignoring my efforts to detatch it. Not cool.

That’s when I remembered Caliburn.Micro‘s support for messaging.

What is messaging?

A message is an object that is broadcast throughout your application when something important happens. When using messaging, an object “publishes” a message, which can be just about anything you want it to be. This object bubbles through your application, moving up the object hierarchy. Other objects that are subscribed to the message will receive it and can take action upon receiving it.

One of the major advantages to messaging is the way it can help you decouple classes. Because the message bubbles through the system, your subscribing code doesn’t need to know about the sender—it just listens for the message.

Traditional event handling, on the other hand, tightly couples classes together. In my timer app I was creating references to a specific instance of a concrete class, then assigning a method to be called when an event on that specific object fired:

CountdownTimer myTimer = new CountdownTimer();
myTimer.TimeExpired += OnTimeExpired;

protected void OnTimeExpired(object sender, EventArgs e)
{
    // Complete actions here.
}

Messaging, Caliburn.Micro style

Caliburn.Micro supports messaging through the EventAggregator class. The EventAggregator is a central hub, or bus, for all messages.

Using the EventAggregator is a two-step process. First, you subscribe to the aggregator in your viewmodel and create methods to handle the messages that class will receive. Second, your model classes publish messages to the aggregator when they have something to communicate.

A simple example

Let’s look at a basic app that employs messaging. Here’s what the app will do:

  • On launch, a page displays with a “Pet the Cat” button and an empty textblock that the cat will use to tell us how it’s feeling.
  • The viewmodel subscribes to messages so it can receive the cat’s response.
  • The “Pet the Cat” button triggers an action in the page’s viewmodel, which in turn calls a method on the cat object.
  • The cat object sends a message.
  • The viewmodel receives the message and it updates a property with the cat’s response. Since this property is databound to the view, the view displays the message automatically.

The full source code is available as a Visual Studio project at the end of the post. Also, I’ve simplified the code at some points in this post for clarity’s sake.

Configuring the bootstrapper

Before I can dive into the application’s logic, I need to do some setup in the AppBootstrapper class:

public class AppBootstrapper : PhoneBootstrapper
{
    PhoneContainer container;

    protected override void Configure()
    {
        ...

        container = new PhoneContainer(this);

        container.RegisterSingleton(typeof(EventAggregator), null, typeof(EventAggregator));
        container.RegisterPerRequest(typeof(MainPageViewModel), "MainPageViewModel", typeof(MainPageViewModel));
        container.RegisterPerRequest(typeof(Cat), null, typeof(Cat));

        ...
    }
}

I registered the EventAggregator class as a singleton, which means that Caliburn.Micro will only create a new instance of the class when it is first requested. Subsequent requests for an EventAggregator object will be supplied with the same instance. This ensures that the EventAggregator that the Cat class notifies will be the same one that MainPageViewModel is subscribed to. I also registering the MainPageViewModel and Cat classes to allow Caliburn.Micro to interact with them.

A simple view

The view is about as straightforward as it gets:

<Grid x:Name="ContentGrid">
    <StackPanel>
        <StackPanel>
            <TextBlock Text="The Cat Says: " />
            <TextBlock Name="CatSound" />
        </StackPanel>
        <Button Name="PetTheCat" />
    </StackPanel>
</Grid>

This example illustrates how Caliburn.Micro’s conventional binding system works. Elements such as buttons and text fields are databound automatically by the framework if their names match. It’s simple, and you get it for free with Caliburn.Micro.

Sending the message

The Cat class is responsible for sending the message that will update the UI:

public class Cat
{
    private EventAggregator eventAggregator;

    public string Sound { get; set; }

    public Cat(EventAggregator eventAggregator)
    {
        this.eventAggregator = eventAggregator;
    }

    public void MakeSound()
    {
        Sound = "Meeeeeeooooowww!";
        eventAggregator.Publish<Cat>(this);
    }
}

Notice that the object’s constructor has a parameter of type EventAggregator. This parameter is supplied automatically by Caliburn.Micro when the Cat object is first created. Enabling this dependency injection is the reason why I registered the EventAggregator and Cat classes in the bootstrapper earlier. When the MakeSound() method executes, the Cat object publishes a message of type Cat to the EventAggregator, and the Cat object supplies itself as the message object to be sent.

Tying it all together

The MainPageViewModel class pulls the pieces together.

public class MainPageViewModel : PropertyChangedBase, IHandle<Cat>
{
    private Cat cat;
    public string CatSound { get; set; }

    public MainPageViewModel(EventAggregator eventAggregator, Cat cat)
    {
        eventAggregator.Subscribe(this);
        this.cat = cat;
    }

    public void PetTheCat()
    {
        cat.MakeSound();
    }

    public void Handle(Cat cat)
    {
        CatSound = cat.Sound;
        NotifyOfPropertyChange(() => CatSound);
    }
}

There are several things to highlight here. First, note that I am subscribing to the EventAggregator in the viewmodel’s constructor. This allows the viewmodel to receive messages from other objects.

Second, the class implements the IHandle interface for the type Cat. This interface dictates that I include a method named Handle() that accepts a parameter of whatever type of message I want the viewmdoel to receive. When a message of type Cat is published, the Handle(Cat cat) method executes, assigning the value of cat.Sound to the CatSound property of MainPageViewModel.

Finally, I’m calling NotifyOfPropertyChange() after updating the CatSound property. This tells the view that a databound property was updated so the view can update itself accordingly.

Download the sample code

A complete Visual Studio project that implements the example above is available here. It was built with the February 2011 version of the Window Phone Developer tools. Other than the WP7 tools, there are no external dependencies. The Caliburn.Micro framework code is included in the Framework folder.

Leave a comment

Filed under Caliburn.Micro, MVVM, Windows Phone 7

Click handler, begone: Databinding a selected list item with Caliburn.Micro

As I’m shifting my mindset from the familiar codebehind style of development into MVVM mode, one area that often trips me up is user interactions that I used to handle with a Click event. I encountered this recently when I added a ListBox to my app. I wanted the app to update some on-screen data elements when the user touched a different item in the list.

In codebehind development, it’s obvious how to handle this: Just define a Click event handler in the list item’s XAML template, then write the logic to change the displayed data based on the selected item.

But how does this work in MVVM, where you don’t use Click events?

More databinding

Databinding is taking over a lot of the tasks I used to perform in my C#, and this is another example. Instead of using a Click handler, the example below binds the ListBox.SelectedItem property directly to a property in the viewmodel–no code required, other than the code that defines the bound properties themselves. Let’s dive in.

Simple viewmodel

There’s nothing particularly special going on in the MainPageViewModel. The List property is a container for the items that will be displayed in the ListBox. (The snippet below omits some code that populates the list with sample items when the constructor is called.) The main thing to note here is the fully implemented SelectedItem property. I used the expanded syntax because I needed to be able to call NotifyOfPropertyChange() when the item selection changes. (If anyone knows of a shorthand way to do this with auto implemented properties, please let me know in the comments.) The NotifyOfPropertyChange() call is what will trigger the UI to update itself. In this case, a TextBlock will update with the title of the selected album.

public class Album
{
    public string Title { get; set; }
    public string Artist { get; set; }
}

public class MainPageViewModel : PropertyChangedBase
    {
        private Album selectedItem;

        public Album SelectedItem
        {
            get
            {
                return selectedItem;
            }
            set
            {
                selectedItem = value;
                NotifyOfPropertyChange(() => SelectedItem);
            }
        }

        public List<Album> MyAlbumList { get; set; }
        
        ...
    }
}

Most of the work happens in the XAML listed below. I’ve stripped out the formatting and boiler plate stuff for clarity. Scan through the whole thing, then we’ll take a look at a few key snippets.

<ListBox ItemsSource="{Binding MyAlbumList}"
         SelectedItem="{Binding SelectedItem, Mode=TwoWay}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <TextBlock Text="{Binding Title}"/>
                <TextBlock Text="{Binding Artist}" />
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>
<StackPanel>
    <TextBlock Text="Selected Album Title:" />
    <TextBlock Name="SelectedItem_Title" />
</StackPanel>

Notice that I’m binding the ItemsSource manually to the MyAlbumList property. There may be a way to accomplish the same result using Caliburn.Micro’s convention-style bindings, but this is how I was able to get it working.

The real magic is in the next attribute, SelectedItem="{Binding SelectedItem, Mode=TwoWay}". When the ListBox selected item changes, Caliburn.Micro assigns the value of the item to the SelectedItem property in the viewmodel. In this example, the viewmodel’s SelectedItem property is of type Album, which is the same type as the items in MyAlbumList.

The Mode=TwoWay setting allows the view to communicate back to the viewmodel. (Omitting this is a common databinding mistake—one I made just the other day. If actions in your UI aren’t triggering the expected response in your viewmodel, double check to make sure twoway binding is set.)

The remaining XAML is standard ListBox for binding to a list. I’m creating a template that will be used for each item and binding the list item’s properties to TextBlocks to display their contents. The Name="SelectedItem_Title" syntax may be unfamiliar; I am using a deep path property binding to get at the title of the selected list item. You could accomplish the same thing by defining a viewmodel wrapper property that returns SelectedItem.Title.

Download the sample code

A complete Visual Studio project that implements the example above is available here. It was built with the February 2011 version of the Window Phone Developer tools. Other than the WP7 tools, there are no external dependencies. The Caliburn.Micro framework code is included in the Framework folder.

5 Comments

Filed under Caliburn.Micro, MVVM, Windows Phone 7

Deep property databinding with Caliburn.Micro

My favorite thing about the Caliburn.Micro MVVM framework is how much plumbing code it is eliminating in my current Windows Phone app. The framework excels at abstracting away the goo required to get stuff to show up on the screen, letting me concentrate on my application’s logic.

One exciting Caliburn.Micro feature is its support for databinding to deep property paths. This translates to fewer “wrapper” properties in my viewmodel—properties whose sole purpose is to expose data contained in other objects.

The old way

Suppose I have a model object, CurrentUser, and I want to display the user’s FirstName property on the page. Before I learned about deep property path binding, I might have written something like this in my viewmodel:

public class MyViewModel
{
    private User currentUser;
    public string UserFirstName { get; set; }

    public void MyViewModel()
    {
        UserFirstName = currentUser.FirstName;
    }
    ...
}

And my XAML might have looked like this:

<TextBlock Name="FirstName" Text="{Binding UserFirstName}" />

Not a horrible ordeal to code, but if you have several page elements that you want to bind this way, the wrapper properties start to pile up, two lines at a time (or more, if you don’t use auto-implemented properties). This code isn’t helping me make my application better—it’s just shuffling existing data from point A to point B.

Deep property binding to the rescue

Deep property databinding allows you to skip the step of creating a wrapper property and bind straight to the nested model object using Model_Property syntax. Here’s how the example above looks when reworked using deep property databinding:

public class MyViewModel
{
    public User CurrentUser { get; private set; }
}

We’re just exposing the user object itself as a property. The magic happens in the XAML:

<TextBlock Name="CurrentUser_FirstName" />

Using conventions, the Caliburn.Micro framework will find the CurrentUser property, then drill down to the CurrentUser.FirstName property and perform the databinding.

So that’s it, and now you can get back to writing the code that allows CurrentUser to do something with your app.

Deep property databinding is covered in the Caliburn.Micro binding conventions documentation.

Download the sample code

A complete Visual Studio project that implements the example above is available here. It was built with the February 2011 version of the Window Phone Developer tools. Other than the WP7 tools, there are no external dependencies. The Caliburn.Micro framework code is included in the Framework folder.

7 Comments

Filed under MVVM, Windows Phone 7

Databinding WP7 lists to singletons with Caliburn.Micro

Databinding still seems a lot like black magic to me: You wave your hands over the keyboard, copy and paste some code from Stack Overflow, utter some dark words, and … it either works or it doesn’t. If it works, you shrug and move on. When it doesn’t … more hand-waving and increasingly dark utterances ensue.

The Caliburn.Micro framework removes a lot of the ceremony behind databinding. In most scenarios you can just name a view element, like a textbox, something like FirstName, and then make sure you have a property named FirstName in your viewmodel. Magic! Instant two-way databinding.

My current Windows Phone 7 project involves a list of data elements that will be displayed on multiple pages in the application. Rather than storing the list in isolated storage and reading it out each time one of the pages needs to display it, I’m making this list a singleton object, which will be created when the app first launches and will survive until the app closes.

The list is injected into each viewmodel that relies on it via the viewmodel’s constructor. Caliburn.Micro includes a simple IoC container that makes the injection process straightforward. Once the list has been injected into the viewmodel, I am storing the list items in a viewmodel property for display in the view.

Caliburn.Micro’s documentation is excellent, but I wasn’t able to find any example code or sample projects that showed how to databind to an injected list. I ended up thrashing around for a few hours before I found the following solution. (A complete sample project will be provided at the end of the post.) We’ll be creating an app that creates a list of cars, stores the list in a singleton object, and displays it on the page.

Let’s start by …

Creating the singleton in the bootstrapper

Any object to which you want to databind in a Caliburn.Micro project needs to be registered in the AppBootstrapper.cs file with the container.RegisterSingleton() method. Note that the second parameter, the key, should be null unless you plan to use the key to access the object later. This had me spinning my wheels for a while until Caliburn.Micro creator Rob Eisenberg pointed out my mistake. Here’s what our bootstrapper looks like:

public class AppBootstrapper : PhoneBootstrapper
{
    PhoneContainer container;

    protected override void Configure()
    {
        LogManager.GetLog = type => new DebugLogger(type);

        container = new PhoneContainer(this);

        container.RegisterPerRequest(typeof(MainPageViewModel), "MainPageViewModel", typeof(MainPageViewModel));
        container.RegisterSingleton(typeof(Cars), null, typeof(Cars));

        ...
       
        AddCustomConventions();
    }
   
    ...
}

Building the model objects

Our model is very straightforward. The Car class contains a few simple properties. The Cars class contains a property that holds a list of Car objects. It also includes a constructor that creates several sample cars for us to work with.

public class Car
    {
        public string Make { get; set; }
        public string Model { get; set; }
        public string Year { get; set; }
    }

public class Cars
    {
        public List Items;

        public Cars()
        {
            Items = new List();
            Items.Add(new Car() { Make = "Toyota", Model = "Camry", Year = "2007" });
            Items.Add(new Car() { Make = "Ford", Model = "Fiat", Year = "1999" });
  Items.Add(new Car() { Make = "Pontiac", Model = "Firebird", Year = "1980" });
            Items.Add(new Car() { Make = "Ford", Model = "Mustang", Year = "1964" });
        }
    }


Injecting the list into the viewmodel

The Caliburn.Micro will handle injecting the list into your viewmodel almost automatically. All you need to do is include the list as a parameter in your viewmodel’s constructor. Inside the constructor, assign the injected object to a property or private variable in the viewmodel so that you can use it later:

public class MainPageViewModel
    {
  private readonly INavigationService navigationService;

  public List CarsList { get; set; }

  public MainPageViewModel(INavigationService navigation, Cars cars)
        {
  navigationService = navigation;
  CarsList = cars.Items;
        }
    }

Note that I am assigning cars.Items to the CarsList property, not just the value of cars. This was another area where I got stuck for a while. I was initially databinding directly to the Cars object, but I later realized that the Cars object contains a list; it is not in and of itself a list.

Binding the list to the view

The final step is to configure the view to display the data from the list. I’m using a ListBox with a ListBox.ItemTemplate. Caliburn.Micro handles the heavy lifting here again. I gave the ListBox an x:Name that matches the property name of the list that you’re binding to—CarsList in this case. This binds the ListBox to the list, but I still need to indicate how the properties of each list item should be displayed.
I created several TextBox elements in the DataTemplate and bound the Text properties to the various properties of the Car object:

<ListBox x:Name="CarsList">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding Make}" />
                <TextBlock Text="{Binding Model}"
                           Margin="15, 0, 0, 0"/>
                <TextBlock Text="{Binding Year}"
                           Margin="15, 0, 0, 0" />
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

Troubleshooting databinding

Currently, the Windows Phone 7 tools don’t provide much in the way of debugging for databinding. Silverlight 5 will include a debug mode, and I’m hoping this will make it into Windows Phone sooner rather than later. In the meantime, here are a few tips that have helped me at various times:

  • Make a quick demo project. This is probably my number one troubleshooting tip of all time. Create a new project and use it to implement the one feature you’re working on. You won’t be worried about messing up your real app code, and you also are able to more easily focus on solving the problem at hand.
  • Confirm that your objects are being populated appropriately. Step through your viewmodel code in debug mode and make sure that properties actually contain the values you think they do. Sometimes the problem isn’t the binding.
  • Use logging. Caliburn.Micro has a nice logging feature, which I’ve enabled in this sample project. It writes to the Visual Studio output console as it attempts to databind each element in your XAML page. You’ll see messages like No convention applied to ApplicationTitle. and Added convention binding for CarsList. that can help you figure out whether the framework is finding the properties you intend to bind to. Rob has an excellent write-up on how to enable logging on his blog.
  • Finally, make sure that you’re binding to the object at the correct level. If you have a list contained in an object, you need to expose the list itself somehow before you can bind to it.

Download the sample code

The sample project is posted in my SkyDrive. It was built with the February 2011 version of the Window Phone Developer tools. Other than the WP7 tools, there are no external dependencies. The Caliburn.Micro framework code is included in the Framework folder.

1 Comment

Filed under MVVM, Windows Phone 7

triggering windows phone 7 animations with mvvm light

Screenshot of Windows Phone 7 application.

Simple is a good thing when you're learning a new technique.

I’m in the process of learning how to apply the MVVM design pattern in my Windows Phone 7 development, but for some reason it’s hard to find simple, working examples that illustrate specific tasks. Most of the blog posts I’ve come across are either highly theoretical, outdated (relying on the CTP version of the WP7 development tools, for example) or too complicated for an MVVM beginner to grasp. Maybe I’m feeble minded, but an MVVM “beginner tutorial” that packages UIs for Windows Phone 7, WPF and Silverlight into a single Visual Studio solution along with separate data access and business logic projects doesn’t help me learn MVVM. It just makes my brain hurt. I just want to know how to make this button click do something useful in my viewmodel.

To that end, this example does just one thing: When you click the Start button, a white circle animates from left to right. Here’s what’s happening behind the scenes:

  • The Start button is bound to a command in the viewmodel.
  • When the command is triggered in the viewmodel, it broadcasts a message, which is really just an object that you define.
  • The codebehind page, which has been listening for the message, starts the animation.

If this seems like extra work, it is. So why not just start the animation from a click event in the codebehind and be done with it? The benefit becomes more obvious later when you add complexity to your app. The message that starts your animation could be used to trigger events in other areas of your application when you want several things to happen simultaneously. You can also write unit tests that validate that your “start animation” message is sent in response to the correct event.

The code download requires Laurent Bugnion’s MVVM Light Toolkit, and I have included the toolkit DLLs in the project. It uses the fall 2010 RTM version of the Windows Phone 7 Developer Tools. I have removed a lot of the stock code that is included in the default MVVM Light template to clarify which code is essential to the example.

Download Example Code

Comments and constructive criticism are welcomed.

Leave a comment

Filed under MVVM, Windows Phone 7