Note: these are early notes based on some initial experiments with the Silverlight 5 beta, apply a pinch of salt to what you read.
A core part of the Silverlight platform and one of its strongest is the data-binding support. However, it’s fair to say that there are times when it causes some late nights when a binding isn’t doing what you expect it to do. Up until Silverlight 5 and Visual Studio 2010 Service Pack 1 my best advice was always;
and I’m pretty sure that I borrowed a few if not all of these from a “diagnostics” talk or blog post on the web somewhere so I’m not claiming they’re original.
With Silverlight 5, there’s the possibility of “debugging the binding”. I recently put together a reasonably comprehensive data-binding demo for the MIX 11 Silverlight Bootcamp sessions so I thought I’d see how data-binding debugging might help me diagnose a few scenarios.
Scenario 1 – Controlling Binding Debugging
The first thing to say is that there’s a fairly simple global flag that you can use to control whether binding debugging is enabled or not. The static property IsDebuggingEnabled on the Binding class controls this;
Binding.IsDebuggingEnabled = false;
this defaults to true so you only have to get involved with it if you want to turn it off.
Scenario 2 – A Misnamed Property
I hacked one of the property names in use on my binding. I have a binding here;
and the name of the property is Room and not Roomy so I set a breakpoint on the binding and can immediately see;
and so that tells me immediately that my RatingSessionViewModel does not have a property called Roomy.
Easy – 10 out of 10 to the debugger.
Scenario 3 – A Private Setter
I have a glorified slider control which is bound in a two-way manner to a nullable integer property called Content and I’ve mistakenly made the setter of the property private which means that my slider;
keeps forgetting its value when I revisit the data;
I set a breakpoint on the binding in question and then changed the data value using the slider. I got this reported from the debugger;
and I feel the need to report that in all its glory because it’s perfect;
System.Exception: System.Windows.Data Error: ConvertBack cannot convert value '2' (type 'System.Int32').
target element is 'BindingPlayground.Controls.RatingControl' (Name='');
target property is 'Rating' (type 'System.Nullable`1[System.Int32]')..
Attempt by method 'System.Windows.CLRPropertyListener.set_Value(System.Object)'
to access method 'BindingPlayground.Model.Rating.set_Content(System.Nullable`1<Int32>)' failed.
Now – I added the formatting there but the rest is the work of the debugger and it’s pure genius because it tells me exactly what the problem is.
Easy – 11 out of 10 to the debugger.
Scenario 4 – An Exception in Conversion
On that same binding, I have a converter which translated from a Nullable<int> to an Image (yes, I know – this was purely for a demo about binding ) and maybe I’ve introduced a bug there which fails to convert a particular numerical value to an image. I know that my ratings have a range 1,2,3,4,5 and the images I’m expecting for those values are;
Here’s a fragment of the code that does that conversion and I’ve deliberately made a mess of the range check;
and that range check there should actually be a 6 rather than a 5 and what that means is that my converter will throw an ArgumentException for the integer value of 5 and that will break the binding.
To see how the debugger might help, I set a breakpoint on the binding and then I moved my slider to produce a value of 5. The Binding looks like this;
and, interestingly, the breakpoint hit for the values of 1, 2, 3, 4 but when I got to the value of 5 the breakpoint simply didn’t fire.
So, the debugger doesn’t seem to help me there except (naturally) I could always tell the debugger to stop on first-chance exceptions and I’d quickly identify the problem that way so there is a way that the debugger can solve this one for me.
Not so easy – I’d give the debugger 4/10 here but maybe I’m missing something?
Scenario 5 – A Null Value from Conversion
I changed the previous example so that rather than throw an exception, my converter returns decent images for the values 1, 2, 3, 4 but returns null for the value of 5 and so that image does not show up correctly in the UI – instead, the TargetNullValue from the binding is used.
Once again, I set a binding in the debugger and this time it was a lot easier to spot my problem. As the values 1,2,3,4 were set in the UI I could see the “post conversion” result as in;
so when the value of 5 passes through the binding I can very easily see;
and so that very nicely tells me that the converter is producing a null I wasn’t expecting and clearly highlights it by showing me that the binding IsUsingTargetNullValue.
Cool – debugger scores 9/10 here
Scenario 6 – Who’s Calling My Property?
I have this property getter;
and it’s bound from many places in the UI and when I’m looking at a breakpoint on the getter it can be pretty tricky to figure out who the caller of my property is.
So, I can take a look at the call-stack;
and then set the stack frame to that highlighted frame that I see and then my locals window shows me;
<snipped a bit of the locals window here>
aha! so it’s the binding on line 135 of RatingSessionView.xaml – excellent!
9/10 for the debugger here.
Scenario 7 – A Null DataContext
I have a main view which sets a DataContext for a sub-view as in;
and then the sub-view has lots of bindings. I figured I’d change the DataContext above to a Null value and then see if I could debug the bindings in the sub-view.
Interestingly, I couldn’t get my breakpoints to fire on a null DataContext so this didn’t really help me in diagnosing this one.
2/10 for the debugger here – perhaps I’m doing something wrong?
Scenario 8 – Debugging Validation on Bindings
I’ve got another UI which presents a child form that allows enter of an “Order” for some fictitious products. This form is very validation centric so I wanted to see what the debugger could tell me about validation events.
Here’s the form;
it’s using INotifyDataErrorInfo and when I go and enter a value for Quanity I get validation errors showing up in a validation summary;
and if I set a breakpoint on the binding in question;
then the debugger stops me as it goes through validation events;
that’s pretty cool – I can see that validation is taking place and that I’m getting some errors coming back here “across” the binding.
The new debugging support helped me in most of the scenarios that I could think of and I think that it’s going to be of huge use – no doubt there’s a few gremlins in there because it’s a beta and that’ll get sorted out on the way to RTM but it’s a very powerful new tool to have for working with your many bindings.
The one thing I’d perhaps want that isn’t present would be an option to break on any failed binding in the application. I know that these can be highlighted in the output window but it’d be a useful thing for the framework to be able to do a Debugger.Break() at the point where any binding fails. I’d love to see that added