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.



