Welcome to Pete Brown's 10rem.net

First time here? If you are a developer or are interested in Microsoft tools and technology, please consider subscribing to the latest posts.

You may also be interested in my blog archives, the articles section, or some of my lab projects such as the C64 emulator written in Silverlight.

(hide this)

Silverlight 5: Debugging Bindings with Xaml Breakpoints

Pete Brown - 13 April 2011

When looking at features in our favorite platforms, we often forget that the tooling gets updated too. For Silverlight 5, one of the most interesting tooling enhancements is the ability to set breakpoints and debug bindings in XAML.

Please note that this article and the attached sample code was written using the Silverlight 5 Beta, available at MIX11 in April 2011, and updated for the Silverlight 5 RC.

Binding problems can be notoriously difficult to debug. There simply was no place to put debug code in, unless you wanted to write a custom debugger value converter and attach that to all your bindings. One misspelled word, or a mistake in the data context, and you would get the silent treatment from the runtime. Of course, many of the errors show up in the Output window, as long as you remember to check it. The binding xaml breakpoints is a more flexible and powerful, so we'll look at that here.

Project Setup

For this project, I'll have a Model folder with the Person class, and a ViewModels folder with the MainViewModel class. The two classes are as follows:

public class Person
{
public string LastName { get; set; }
public string FirstName { get; set; }
}


public class MainViewModel
{
private Person _currentPerson;
public Person CurrentPerson
{
get { return _currentPerson; }
set { _currentPerson = value; }
}

public MainViewModel()
{
// load up dummy data
CurrentPerson = new Person() { LastName = "Brown", FirstName = "Pete" };
}
}

Then, in the MainPage.xaml.cs code-behind, I wire up the ViewModel

public partial class MainPage : UserControl
{
private MainViewModel _vm = new MainViewModel();

public MainPage()
{
InitializeComponent();

DataContext = _vm;
}
}

Finally, in the UI for MainPage, I have the following markup:

<Grid x:Name="LayoutRoot" Background="White">
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding LastName}" />
<TextBlock Text="{Binding FirstName}" />
</StackPanel>
</Grid>

Running the App

Now, run the application. What do you see? Nothing you say? Well, I guess we need to find out what is going on! We should have seen the last name and first name displayed on the form.

In the XAML for MainPage.xaml, click in the well to the left to place breakpoints on LastName and FirstName:

image

Now run the application again. Almost immediately, you'll hit the breakpoint. Click on the Locals window tab, and you'll be presented with a bunch of information:

image

If we expand the error property, we can see the following message:

System.Windows.Data Error:
BindingExpression path error: 'LastName' property not found
on 'DebuggingBindings.ViewModels.MainViewModel'
'DebuggingBindings.ViewModels.MainViewModel' (HashCode=40362448).

BindingExpression: Path='LastName'
DataItem='DebuggingBindings.ViewModels.MainViewModel'
(HashCode=40362448);

target element is 'System.Windows.Controls.TextBlock' (Name='');
target property is 'Text' (type 'System.String')..

Excellent! Well, that tells us that there's no LastName property on the MainViewModel (the class that is the data context). Oh, duh! I meant to dot down on the CurrentPerson property of the viewmodel, so let's fix that.

Once you fix the XAML, run it again and hit the breakpoints. The breakpoints are set to be hit no matter what, so you can drill down into them and see the binding value. IN this case, Under FinalSource, we see the property is CurrentPerson and the values FirstName and LastName are correct, so we know we're now binding to the correct object.

image

Conditional Breakpoints

But what if you don't want to hit all those breakpoints in your application? Well, there's a long path you can use to conditionally break only when there are errors (thanks to John Papa for digging this one up!)

Set a conditional breakpoint on the line of Xaml with the binding, then enter this as the condition:

((System.Windows.Data.Debugging.BindingDebugState)BindingState).Error != null

Now, run the application. You shouldn't hit the breakpoint because we fixed the bindings earlier. Stop running and make the bindings error again (misspell something) and run the application. Bam! You hit the breakpoint. Lovely to have something we've relied on in code now available to our markup.

 

Source code for the Silverlight 5 Beta version of this application may be downloaded via the link below.

A video version of this tutorial will be on Silverlight.net shortly.

       

Source Code and Related Media

Download /media/76828/debuggingbindings.zip
posted by Pete Brown on Wednesday, April 13, 2011
filed under:        

11 comments for “Silverlight 5: Debugging Bindings with Xaml Breakpoints”

  1. Fredriksays:
    I don't know about WPF, but at least in SL4 (and earlier?) you can check the debug output window for BindingExpression path error when you load a XAML page. It will list all missing binding paths for current view.
  2. MEKsays:
    Too bad that it is not going to make it for WPF I had really hoped they would port it from Silverlight when it was announced in Silverlight some time ago. I hope we do not have to wait 2 years for it in WPF v6.
    Even though I have no idea how this is implemented in Visual Studio there should not be a big difference in implementing it for WPF and Silverlight. I assume the binding concept is pretty much the same?
  3. Petesays:
    FWIW guys, WPF had better XAML debugging than Silverlight in VS2010. There's an option to turn on verbose binding reporting. Silverlight didn't have that.

    I know it's not quite the same thing as setting a breakpoint, but it is useful for sure.

    @MEK While from the outside they're very similar, the Silverlight and WPF codebases are very very different. It's actually a ton of work to implement some things in WPF due to those differences. In fact, most of Silverlight is native code whereas much of WPF is managed. If it were just an easy imp, the team would have done it.

    That said, we know everyone wants it.

    Pete

Comment on this Post

Remember me