Archive for the ‘Silverlight’ Category

Databinding in Silverlight 5

Thursday, December 2nd, 2010

Microsoft hosted a Silverlight Firestarter event. It was important for Microsoft to reset the Silverlight message after the Mary Jo Foley incident at PDC10. The most important piece in this strategy was Silverlight 5.

I was very excited today to see some of the new features coming in Silverlight 5 to support databinding. As Scott Guthrie says, this will bring Silverlight into even better parity with WPF. There are two features that I think are most important: implicit DataTemplates and markup extensions.

Implicit DataTemplates

I am a big believer in creating a DataTemplate based on the type, rather than explicitly setting a DataTemplate in XAML. This supports polymorphism to the view. If you have a heterogeneous list, this technique lets you express the view of each element declaratively. If you add a new type of item to the list, you just add a new DataTemplate to your resources.

Most importantly, this lets the View Model be in control. I’ve often said that the view model locator pattern is backwards. When the view locates the view model, navigation goes to the view first. This leads to some awkward code. But when we navigating to a view model, all of the navigation code is naturally in the right place. We can allow the resources to determine the correct DataTemplate. This technique is covered in Convention-based view model registration.

Markup extensions

The original Update Controls XAML interface was a binding extension. That is why it took so long to port Update Controls to Silverlight. The Update markup extension provided WPF data binding without INotifyPropertyChanged. It bound directly to your view model.

To support Blendability, and to enable the Silverlight port, I added ForView.Wrap() to the library. This method wraps your view model so that the built-in Binding markup extension can use it. The wrapper has many disadvantages:

  • It hides data annotations like Required and Display.
  • It adds a performance tax because it uses reflection and (in the Silverlight versions) DependencyProperties.
  • It requires you to call ForView.Unwrap() whenever accessing objects in code behind.
  • It interferes with implicit DataTemplates.

The benefits of Blendability and Silverlight support outweighed these disadvantages, so it was with great sadness that I changed my recommended approach from the Update markup extension to ForView.Wrap(). Silverlight 5, however, is going to give me the choice back. If I can find a way to change how Blend does databinding, I’ll have the best of both worlds.

What does this mean for Update Controls

There will be a new version of Update Controls as soon as I get my hands on the Silverlight 5 bits. It will reintroduce the Update markup extension to Silverlight. I expect this version to be closer to the WPF code base, which should make code maintenance easier.

This also means that more Update Controls demos are coming. The joy of knowing that improvements are coming was sullied every time a demo implemented INotifyPropertyChanged. That interface is a stick in the eye every time I see it. It especially hurts when I see John Papa list INPC as one of the benefits of RIA services. I want everyone who watched the Silverlight Firestarter to be able to compare those demos with ones that don’t have the code clutter and pain of this extraneous interface. Let it be known that INotifyPropertyChanged is Obsolete, now more than ever.

Silverlight ComboBox sets SelectedItem when DataContext changes

Friday, June 18th, 2010

I think we can officially call this a bug in Silverlight. Create a master list and a detail view. Bind the SelectedItem of a combo box in the detail view to a reference typed property. Silverlight will set the property to null when you select a new item in the master list.

Try it out below. The list on the left displays the person’s name and preferred phone number. Select “Michael”, and the detail pane shows his phone number and favorite color. Then select “Jenny”. Notice that Michael’s phone number disappeared. Click back on him and see that the phone number is indeed gone.

Favorite color is an enumeration – a value type. Phone number is a class – a reference type. Even though the phone number has a valid Equals and GetHashCode implementation, Silverlight treats it differently. For some reason, it decides it needs to set it to null whenever the DataContext changes.

This behavior is clearly incorrect. The list of items does not contain the value “null”. Even if it did, the user did not select “null”. And as further evidence, WPF does not behave this way. Download the source code, which has been compiled for both Silverlight and WPF. The WPF version of exactly the same source code behaves correctly.

Here’s my solution
Any property bound to SelectedItem should protect itself from a null assignment. In this case:

public PhoneNumber PreferredPhone
    get { return _preferredPhone; }
        if (value == null)

        _preferredPhone = value;

What if null is a valid value for the property? Then represent null with a stand-in. Perhaps two classes could implement a common IPhoneNumber interface: PhoneNumber and NullPhoneNumber.

It’s a pretty simple workaround, but still an embarrassing bug in Silverlight.