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

Using display ads in Windows Phone 7 apps

Enabling display ads in a Windows Phone 7 app is a three-step process:

  1. Installing the Microsoft Advertising SDK.
  2. Registering the application with the Microsoft pubCenter.
  3. Embedding the ad control in the application.

Installing the SDK

The Microsoft Advertising SDK is available on the Microsoft Advertising site. The SDK is an .msi installer file, and executing it copies several .dlls and help files to the program files directory. On my PC the files are located in:

C:\Program Files (x86)\Microsoft Advertising SDK for Windows Phone 7

Registering the app

There are two main goals in the registration process:

  1. Subscribing your app to several ad channels that will be relevant to the app’s users.
  2. Obtaining unique ad unit and application IDs. These ties your app to the channels you select and are used to track the number of impressions your app generates.

To register your app:

  1. Visit the Microsoft Advertising pubCenter and either create a new account or use your existing Microsoft Live account to sign in.
  2. Click Setup, then Register. Enter your app’s name and click Save. Your app will appear under the Sites & apps tab. Notice the application ID; you’ll need it later.
  3. Click Ad unit, then select Create a new application ad unit.
  4. Enter a name for the ad unit, then select up to three categories. These determine the types of ads your users will see, so choose categories that seem relevant.
  5. Click Save. Note the ad unit ID; you’ll need this one later as well.

Embedding the ad control

Before you can implement the ad control in your app, you need a reference to Microsoft.Advertising.Mobile.UI, which you can add by right-clicking on the References folder in the Solution Explorer, then clicking Add Reference. Browse to the advertising SDK folder and select the Silverlight .dll.

Open the XAML page that will hold your ad control, and add an XML namespace for the advertising assembly:

<phone:PhoneApplicationPage x:Class="Wp7AdControlSetup.MainPage"
                            ...
                            xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
                            ...
                            shell:SystemTray.IsVisible="True">

Next, insert the ad control itself into your XAML page:

<advertising:AdControl ApplicationId="test_client"
                               AdUnitId="Image480_80">
                               </advertising:AdControl>

The ad control is now installed and set up to run in test mode.

Test mode vs. production mode

When the ad control is configured for test mode, you should see something like this when you run the app in the emulator:

Test ads

Sometimes the ads take a few seconds to start loading, but if you don't see anything after a minute or two, something is set up incorrectly.

You can also view live ads in the emulator and on your unlocked device before publishing your app to the Marketplace. Production ads look like this:

Live ads

Switching the ad control to show live ads involves adding production ad and unit IDs to the control's XAML and disabling test mode for your application. First, add the app and ad unit IDs that you received during the pubCenter registration process to the advertising control:

<advertising:AdControl ApplicationId="3a6a7b1b-3b66-4fa0-9732-514fc9aa8b89"
                       AdUnitId="10016058"
                       AdModel="Contextual" />

Next, open up the App.xaml.cs file and add the following code in the public App() constructor, beneath the InitializeComponent() method:


public App()
{
    ...
    InitializeComponent();

    AdControl.TestMode = false;
    
    ...
}

Failing to set the AdControl.TestMode early enough in the application's lifecycle will cause the ad control to load an empty frame. Setting it in the application's constructor ensures that it is set before the control itself is rendered.

If you want to revert to test ads, reinsert the test app and ad unit IDs and remove the line that sets AdControl.TestMode = false.

Download the sample

A full working example is available on my CodePlex site. The sample includes real ad unit and application IDs so you can see live ads in the emulator. It was built with the February 2011 version of the Windows Phone developer tools. A reference to the advertising .dll is included, but you will probably need to relink the .dll to your local copy of the advertising SDK.

1 Comment

Filed under Windows Phone 7

New Visual Studio extension for debugging XAML databinding expressions

A subgroup of the Windows Phone 7/Silverlight team, headed by Jeff Wilcox, just released an extension for Visual Studio 2010 that takes the pain out of debugging XAML databinding expressions.

The extension, which Microsoft marketing has awkwardly dubbed the Productivity, Refactoring And Notification Konnector, allows you to set breakpoints in your XAML and see what values are being applied at runtime.

Quick look

Using the extension is simple. Just set a breakpoint in your XAML page like you would in C#. As you can see, Visual Studio hits the breakpoint, and you can explore the bound properties or collection.

The new Visual Studio XAML debugger takes the pain out of databinding.

The Productivity, Refactoring And Notification Konnector add-in was released 4/1/2011.

2 Comments

Filed under 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