Binding to Dynamic Properties

Sometimes, you need to bind to data that you don't know the structure of at design time, such as XML or JSON data. In this type of scenario, ideally, you'd be able to create an object at runtime that you could deserialize the data to and then bind to it. Silverlight 4 added support for dynamic types, which goes some way toward solving the issue. However, the downside to creating dynamic objects is that you can't actually bind to them, as Silverlight's binding engine doesn't recognize dynamic properties as real properties. Any attempt to bind directly to dynamic properties on objects will fail. To overcome this issue, Silverlight 5 introduced the ICustomTypeProvider interface that you can implement on a class to tell the binding engine what the structure of the object is.

The ICustomTypeProvider interface can be found in the System.Reflection namespace and simply requires the implementation of a single method: GetCustomType. However, the actual implementation of this method is unfortunately quite complex. You essentially need to create a type from scratch. The Type class is unsealed in Silverlight 5, enabling you to inherit from it and override its properties and methods.

Rather than writing this ICustomTypeProvider implementation yourself, Alexandra Rusina, a program manager in the Silverlight team at Microsoft, has created a helper class that will do the hard work for you, which you can download here: http://blogs.msdn.com/b/silverlight_sdk/archive/2011/04/26/binding-to-dynamic-properties-with-icustomtypeprovider-silverlight-5-beta.aspx. Using this helper class, you can then create a class that either inherits from this helper class (the easiest method) or implements the ICustomTypeProvider interface and delegates the GetCustomType method to the helper class. Use the latter method if your class already inherits from another class.

For example, let's create a Product class whose structure we'll define at runtime.

  1. Start by creating the class, and inherit from the generic CustomTypeHelper class:
    public class Product : CustomTypeHelper<Product> { }
  2. Add properties to the class by calling the static AddProperty method that's been inherited from the CustomTypeHelper<T> class, giving each property a name and a type:
    Product.AddProperty("ProductName", typeof(string));
    Product.AddProperty("Category", typeof(string));
    Product.AddProperty("QtyAvailable", typeof(int));
  3. When you instantiate the class, you obviously won't be able to set the values for these properties in the way you would normally with properties defined at design time. Instead, you'll need to call the SetPropertyValue method on the Product class (again, inherited from the CustomTypeHelper<T> class), passing it the name of the property to set the value for, and its new value, like so:
    Product product = new Product();
    product.SetPropertyValue("ProductName", "Helmet");
    product.SetPropertyValue("Category", "Accessories");
    product.SetPropertyValue("QtyAvailable", 10);
  4. You can now bind to this object and its properties in exactly the same way as you would any standard CLR object. Thanks to the helper class, the properties automatically implement the INotifyPropertyChanged interface, so you don't need to worry about that aspect. If necessary, you can get the property values in code using the GetPropertyValue method that the Product class has inherited from CustomTypeHelper<T>:
string productName = (string)product.GetPropertyValue("ProductName");
string category = (string)product.GetPropertyValue("Category");
int qtyAvailable = (int)product.GetPropertyValue("QtyAvailable");

images Note Rather than write your own ICustomTypeProvider implementation to wrap XML or JSON data from scratch, Matt Duffield has provided ICustomTypeProvider implementations for these types of data that you may wish to try: http://mattduffield.wordpress.com/2011/09/16/using-icustomtypeprovider-in-silverlight-5-with-xml.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset