Colin Eberhardt's Technology Adventures

New codeproject article on WPF, Silverlight + T4 Templates

April 28th, 2009

I have just finished a new article on codeproject:

Generate WPF and Silverlight Dependency Properties using T4 Templates

It is an extension of my previous blog post regarding Silverlight DP generation, adding attached properties, comments, metadata and WPF support. Enjoy!

codeproject

Binding a Silverlight DataGrid to dynamic data Part 2 – editable data and INotifyPropertyChanged

April 22nd, 2009

UPDATE: This blog post was written with a SL2 DataGrid, for SL3, please see my updated blog post.

In my previous blog post I described a method for solving the commonly faced problem of binding a Silverlight DataGrid to dynamic data, the form of which is not know at compile time. This blog post extends on the method previously described, adding change notification, allowing the DataGrid to synchronise the UI with changes to the bound data and to allow the user to edit the DataGrid’s contents.

To briefly recap my previous post, the dynamic data is copied to a collection of Rows:

public class Row
{
  private Dictionary<string, object> _data = new Dictionary<string, object>();
 
  public object this [string index]
  {
    get { return _data[index]; }
    set { _data[index] = value; }
  }
}

Where the row ‘properties’ which are implemented via the string indexer bound to the grid via a ValueConverter. The XAML for the DataGrid looks like the following:

<data:DataGrid Name="_dataGrid" AutoGenerateColumns="False"  IsReadOnly="False" Margin="5">
    <data:DataGrid.Columns>
        <data:DataGridTextColumn Header="Forename"
                                 Binding="{Binding Converter={StaticResource RowIndexConverter},
                                    ConverterParameter=Forename}"/>
        <data:DataGridTextColumn Header="Surname" 
                                 Binding="{Binding Converter={StaticResource RowIndexConverter},
                                    ConverterParameter=Surname}"/>
        ...               
    </data:DataGrid.Columns>
</data:DataGrid>

Where the ValueConverter takes the ConverterParameter and uses it to index the bound Row instance:

public class RowIndexConverter : IValueConverter
{
  public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  {
    Row row = value as Row;
    string index = parameter as string;
    return row[index];
  } 
}

It is important to note that the Binding does not have a Path defined. As a result, the binding source is the Row instance itself rather than a property of the Row as would more normally be the case when binding data. The rest of the post described how to create a collection view which sorts the collection via the Row’s string indexer. You can read about this in full in my previous blog post.

Now, one question a few people have asked me is how to implement INotifyPropertyChanged on the Row class in order to make the DataGrid editable. Simply implementing INotifyPropertyChanged on the Row class, with events raised from the index setter, will not make the grid editable or synchronised with the bound data. The underlying problem here is that the Binding does not have a Path specified, therefore, the binding framework does not know which property name to look out for when handling PropertyChanged events. Interestingly I would expect the above bindings to be updated if a PropertyChanged event were raised with a null or empty PropertyName string, however they do not.

So if the Binding framework needs a Path for the binding in order for change notification to work, we will have to fabricate one for this purpose! We can modify the Row class as follows, adding a Data property which is simply a reference to the Row instance itself:

public class Row : INotifyPropertyChanged
{
    private Dictionary<string, object> _data = new Dictionary<string, object>();
 
    public object this [string index]
    {
        get
        {
            return _data[index];
        }
        set
        {
            _data[index] = value;
 
            OnPropertyChanged("Data");
        }
    }
 
    public object Data
    {
        get
        {
            return this;
        }
    }
 
    public event PropertyChangedEventHandler PropertyChanged;
 
    protected void OnPropertyChanged(string property)
    {
        if (PropertyChanged!=null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(property));
        }
    }
}

In order to bind this class we modify our bindings so that the source Path points to the Data property:

...
<data:DataGridTextColumn Header="Forename"
                           Binding="{Binding Path=Data, Converter={StaticResource RowIndexConverter},
                           ConverterParameter=Forename}"/>
<data:DataGridTextColumn Header="Forename"
                           Binding="{Binding Path=Data, Converter={StaticResource RowIndexConverter},
                           ConverterParameter=Surname}"/>
...

With this change in place, all of our bindings are bound to the Row’s Data property. Again, the Row’s indexer is being accessed via our value converter. However, if any ‘property’ change via the string indexer setter will result in all of our bindings being updated for that Row. I know, it is not the most efficient solution – but at least it work!

The next problem is making the DataGrid editable. The problem we face here is that all of our bindings are to the same property, Data. When a cell is edited, the binding framework will quite happily call the Data properties setter, with the updated value. However, how do we know which property of the Row was really being set? The only place we hold this information is in the ConverterParameter which is fed to our RowIndexConverter value converter. Fortunately, there is a solution to this problem, when the binding framework updates the bound object, it will first invoke the ConvertBack method on our value converter. This gives us the opportunity to ‘capture’ the converter parameter and feed it into the setter of our Data property, as shown below:

public class RowIndexConverter : IValueConverter
{
    ...
 
    public object ConvertBack(object value, Type targetType,
        object parameter, CultureInfo culture)
    {
        return new PropertyValueChange(parameter as string, value);
    }
}

Where PropertyValueChanged is a simple value object:

public class PropertyValueChange
{
    private string _propertyName;
    private object _value;
 
    public object Value
    {
        get { return _value; }
    }
 
    public string PropertyName
    {
        get { return _propertyName; }
    }
 
    public PropertyValueChange(string propertyName, object value)
    {
        _propertyName = propertyName;
        _value = value;
    }
}

The setter for the Data property will now be invoked with an instance of PropertyValueChanged, giving it all the information it requires to invoke the string indexer with the correct ‘property’ name:

public class Row : INotifyPropertyChanged
{
    ...
 
    public object Data
    {
        get { return this; }
        set
        {
            PropertyValueChange setter = value as PropertyValueChange;
            _data[setter.PropertyName] = setter.Value;
        }
    }
    ...
}

With this change in place, we the user is able to edit the data bound to the DataGrid, and the binding ensures that the DataGrid UI is synchronised with any changes to the bound data that may happen elsewhere in our code.

One final thought that struck me is that this technique uses the Binding’s associated ValueConverter to access the Row’s string indexer, but what if we wanted to use a ValueConverter for something else like formatting? Fortunately it is a pretty straightforward process to nest one value converter inside another. For details, see the attached project. For now, have quick play with the grid below, where all the columns are editable and the button click event sets the Row’s Age property demonstrating how the DataGrid is synchronised:

private void Button_Click(object sender, RoutedEventArgs e)
{
    // demonstrate the property changes from code-behind still work.
    Random rand = new Random();
    foreach (var row in _rows)
    {
        row["Age"] = rand.Next(10) + 5;
    }
}

Also, the Age column has a value converter associated …

So there you have it, binding to dynamic data with INotifyPropertyChanged implemented and an editable DataGrid. The only reservation I have with this technique is that I am really bending the binding framework to achieve the results, having a Data property which expects different types for the getter and setter is a little ugly … use with caution!

You can download the project sourcecode: silverlightdynamicbinding2.zip

Regards, Colin E.

Binding a Silverlight DataGrid to dynamic data via IDictionary

April 17th, 2009

This post demonstrates a technique for binding a Silverlight DataGrid to dynamic data, the structure of which is not know at compile-time …

UPDATE #1: I have extended this technique to add include change notification so that the DataGrid can be made editable. Read all about it in part two.

UPDATE #2: This blog post was written with a SL2 DataGrid, for SL3, please see my updated blog post.

With Silverlight binding data to a DataGrid is a very straightforward process. With an XML datasource, you can simply parse your data via Linq to SQL into an anonymous type then bind the resulting collection to the grid. Just a few simple lines of code. But, what if the data you want to bind to your grid is dynamic? That is, at compile time you do not know how many columns are required, or what their contents is. This is a common problem that Silverlight users have faced again, and again, and again and again!

The most obvious solution to this problem is to create a dictionary for each row of your DataGrid, and bind your columns to your values via the dictionary’s string indexer:

Binding="{Binding Path=[Name]}"

However, unfortunately the PropertyPath syntax used for binding does not understand indexers, making it impossible to bind to a dictionary.

Vladimir Bodurov presents an ingenious solution to this problem by dynamically generating a new Type based on the values present within the dictionary, i.e. If the dictionary contains the keys “Name” and “Age”, a Type will be generated that has properties of Name and Age. Crazy stuff! Here I would like to show an alternative method that does not use intermediate Language or other black magic!

We will start with a simple example of a class which can be used to store ‘dynamic’ data for rendering in our DataGrid:

public class Row
{
  private Dictionary<string, object> _data = new Dictionary<string, object>();
  public object this [string index]
  {
    get { return _data[index]; }
    set { _data[index] = value; }
  }
}

We can populate a collection of these objects and associate them with a DataGrid as follows:

Random rand = new Random();
 
var rows = new ObservableCollection<Row>();
for (int i = 0; i < 200; i++)
{
  Row row = new Row();
  row["Forename"] = s_names[rand.Next(s_names.Length)];
  row["Surname"] = s_surnames[rand.Next(s_surnames.Length)];
  row["Age"] = rand.Next(40) + 10;
  row["Shoesize"] = rand.Next(10) + 5;
  rows.Add(row);
}
 
_dataGrid.ItemsSource = rows;

However, as mentioned earlier, we cannot create a binding path that accesses our Rows indexer, so just how do we bind the columns to our data?

The classic .NET solution to this problem would be to create a custom property descriptor. When databinding, the properties of an object are not accessed directly, rather they are accessed via their associated property descriptor. A custom property descriptor can be supplied for our Row class, via the ICustomTypeDescriptor interface for example, that exposes properties which when accessed invoke our indexer. This is how the .NET DataRowView exposes its properties. Unfortunately there is one small snag here … Silverlight does not include the required interfaces to create custom properties.

A simple workaround to this problem is to use a binding that binds each row directly to each Row item rather than a specific property of the item, then use a value converter to access the indexer and extract the required value. Here is an example:

<data:DataGrid Name="_dataGrid" AutoGenerateColumns="False" Height="300" IsReadOnly="False">
  <data:DataGrid.Columns>
    <data:DataGridTextColumn Header="Forename" Binding="{Binding Converter={StaticResource RowIndexConverter}, ConverterParameter=Forename}"/> 
    <data:DataGridTextColumn Header="Surname" Binding="{Binding Converter={StaticResource RowIndexConverter}, ConverterParameter=Surname}"/> 
    <data:DataGridTextColumn Header="Age" Binding="{Binding Converter={StaticResource RowIndexConverter}, ConverterParameter=Age}"/> 
    <data:DataGridTextColumn Header="Shoesize" Binding="{Binding Converter={StaticResource RowIndexConverter}, ConverterParameter=Shoesize}"/> 
  </data:DataGrid.Columns>
</data:DataGrid>

And here is the value converter:

public class RowIndexConverter : IValueConverter
{
  public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  {
    Row row = value as Row;
    string index = parameter as string;
    return row[index];
  }
 
  public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
  {
    throw new NotImplementedException();
  }
}

In the above XAML, the binding expression does not have a Path specified, therefore, the binding source is our Row instance rather than a property of the Row. The RowIndexConverter value converter simply uses the supplied ConverterParameter for each column to access the Row indexer and extract the correct value. This works quite nicely, and we are able to see our data within the grid:

grid

However, there is one problem here, if you click on the column headers the grid does not sort the data. The columns of a DataGrid have CanUserSort and SortMemberPath properties, however setting these will not help because the DataGrid will expect the bound object to have a property with the given name which of course it does not! To solve this problem (without resorting to dynamically generated types) we need to delve a little deeper into the way in which the DataGrid binds to the data.

A lot of insight can be gained from the documentation of ICollectionView:

The DataGrid control uses this interface to access the indicated functionality in the data source assigned to its ItemsSource property. If the ItemsSource implements IList, but does not implement ICollectionView, the DataGrid wraps the ItemsSource in an internal ICollectionView implementation.

The ICollectionView interface is responsible for filtering, sorting and grouping of the data bound to the DataGrid. WPF also has the ICollectionViewinterface, you can read a good overview of its features on Marlon Grech’s blog. However, whereas WPF wraps the DataContext itself in a view which is shared across multiple controls, it would appear that Silverlight restricts its usage to the DataGrid. This causes problems if, for example, you want to synchronize the current item between controls (However, Laurent Bugnion has a novel solution for emulating this behaviour).

So, it is the ICollectionView which is responsible for sorting our data. The internal implementation of this interface which the DataGrid creates will expects our object to expose the bound properties, which explains why it does not work. However, if we supply our own ICollectionView interface, we can take control of sorting and implement it ourselves, accessing our ‘property’ values via the Row’s string indexer.

The ICollectionView interface has a lot of methods, events and properties, fortunately I was able to find a suitable implementation of this interface on Manish Dalal’s blog. He had implemented this interface, on a class which extends ObservableCollection, in order to bind a DataGrid to a collection where the data from the server is being paged, hence sorting must be done server side. This gives us pretty much everything we need here, a collection class which is able to manage sorting itself. The only change required is to the ICollectiomView.Refresh() method which is responsible for refreshing the view after the SortDescriptions have changed.

The implementation of this method is as follows:

public class SortableCollectionView : ObservableCollection<Row>, ICollectionView
{
 
  ...
  public void Refresh()
  {
      IEnumerable<Row> rows = this;
      IOrderedEnumerable<Row> orderedRows = null;
 
      // use the OrderBy and ThenBy LINQ extension methods to
      // sort our data
      bool firstSort = true;
      for (int sortIndex = 0; sortIndex < _sort.Count; sortIndex++)
      {
          SortDescription sort = _sort[sortIndex];
          Func<Row, object> function = row => row[sort.PropertyName];
          if (firstSort)
          {
              orderedRows = sort.Direction == ListSortDirection.Ascending ?
                  rows.OrderBy(function) : rows.OrderByDescending(function);
 
              firstSort = false;
          }
          else
          {
              orderedRows = sort.Direction == ListSortDirection.Ascending ?
                  orderedRows.ThenBy(function) : orderedRows.ThenByDescending(function);
          }
      }
 
      _suppressCollectionChanged = true;
 
      // re-order this collection based on the result if the above
      int index = 0;
      foreach (var row in orderedRows)
      {
          this[index++] = row;
      }
 
      _suppressCollectionChanged = false;
 
      // raise the required notification
      this.OnCollectionChanged(
          new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
   }
 
  ...
}

When the user clicks on a grid view header, it modifies the bounds ICollectionView.SortDescription to reflect this change in state. The implementation of ICollectiomView from Manish’s blog invokes the Refresh method whenever the ICollectionView.SortDescription collection changes. In the above implementation we use the OrderBy and ThenBy LINQ extension methods to order the data. Interestingly, OrderBy is a method on IEnumerable, whereas ThenBy is a methods on the IOrderedEnumerable, hence the funny looking logic involving ‘firstSort’. Once the sorting has been performed, the underlying collection is re-ordered to match. The only subtle part is that we use a boolean field, _suppressCollectionChanged to suppress the numerous CollectionChanged events that would be fired by ObservableCollection during this process. Finally we raise NotifyCollectionChanged, resulting in the DataGrid updating to reflect the sort order.

Putting it all together, we simply populate our SortableCollectionView and bind this to the DataGrid, modifying the XAML to explicitly inform the grid that it can sort and which property each column sorts on (usually this is inferred from the Binding Path):

<data:DataGrid Name="_dataGrid" AutoGenerateColumns="False"  IsReadOnly="False" Margin="5">
    <data:DataGrid.Columns>
        <data:DataGridTextColumn Header="Forename" CanUserSort="True" SortMemberPath="Forename" 
                                  Binding="{Binding Converter={StaticResource RowIndexConverter},
                                    ConverterParameter=Forename}"/>
        <data:DataGridTextColumn Header="Surname" CanUserSort="True" SortMemberPath="Surname" 
                                 Binding="{Binding Converter={StaticResource RowIndexConverter},
                                    ConverterParameter=Surname}"/>
        <data:DataGridTextColumn Header="Age" CanUserSort="True" SortMemberPath="Age" 
                                 Binding="{Binding Converter={StaticResource RowIndexConverter},
                                    ConverterParameter=Age}"/>
        <data:DataGridTextColumn Header="Shoesize" CanUserSort="True" SortMemberPath="Shoesize" 
                                 Binding="{Binding Converter={StaticResource RowIndexConverter},
                                    ConverterParameter=Shoesize}"/>                
    </data:DataGrid.Columns>
</data:DataGrid>

And here it is in action:

You can download the complete solution here: silverlightdynamicbinding.zip.

Regards,
Colin E.

Silverlight Dependency Property Code Generation

April 1st, 2009

This blog details a technique for generating Silverlight dependency properties from an XML file via a T4 template. If you just want to grab the code, scroll to the bottom of this article and download the sourcecode or cut and paste the templates. If you want to find out how and why I created this template, please read on …

Personally I find one of the most frustrating aspects of Silverlight and WPF development is working with the dependency property framework. They are beautiful in concept, but completely ugly in their implementation!

Take for example the following dependency property declaration:

public double Maximum
{
    get { return (double)GetValue(MaximumProperty); }
    set { SetValue(MaximumProperty, value); }
}
 
public static readonly DependencyProperty MaximumProperty =
    DependencyProperty.Register("Maximum", typeof(double),
    typeof(RangeControl), new PropertyMetadata(0.0, OnMaximumPropertyChanged));
 
 
private static void OnMaximumPropertyChanged(DependencyObject d,
    DependencyPropertyChangedEventArgs e)
{
    RangeControl myClass = d as RangeControl;
    myClass.OnMaximumPropertyChanged(e);
}
 
private void OnMaximumPropertyChanged(DependencyPropertyChangedEventArgs e)
{
    // do something
}

The above code defines a dependency property, Maximum, providing a type and default value, a CLR property wrapper and a method which is invoked on property change. We have 21 lines of quite densely packed code, which does so little! Furthermore, dependency property declarations can be quite error prone; if incorrectly specified the error can easily go undetected and unreported, wasting precious hours …

A few people have created code snippets which help automate the construction of this ghastly boiler-plate code. They are a few snippets available for Silverlight and whole host available WPF courtesy of the good Dr. These certainly help you get started, however, when refactoring or re-organising code you are back to a more manual approach.

Before I describe my approach, I want to briefly explain why dependency properties (DP) have to be this way. An obvious beginner question is, why can’t CLR properties behave like DPs? The difference is that CLR properties are understood by the compiler, they are part of the language. Whereas DPs are purely implementation, an implementation which is restricted by the .NET language.

So, if we can’t change the language itself, what can we do? I toyed with the idea of Aspect Oriented Programming, enhancing the compiled bytecode in order to add DPs for CLRs marked with attributes, however whichever way I looked at the problem I could not find a solution that fits. This lead me onto code generation, the basic idea being that my DPs would be generated from a concise description of my Dependency Objects. This investigation lead me to one of Visual Studios best kept secrets, T4 templates (T4 = Text Template Transformation Toolkit!).

T4 template are available in Visual Studio 2008, however they are not listed when you select ‘Add => New Item’ on you project. To add a new template, simply create a new file with an extension of ‘tt’. You will then see something that looks like the following:

t4template

Your template file is visible within the solution explorer along with the file that it generates. The templates themselves are executed before Visual Studio compiles your project, so in the example above HelloWorld.cs, our generated file, is compiled just like any other ‘cs’ file. Here’s a simple example, the following template (which has a ASP.NET-like syntax) creates a .cs file, whilst the template language itself is C#.

<#@ output extension="cs" #>
<#@ template language="C#" #>
public class HelloWorld
{
	public string GetTime()
	{
		return "<#= DateTime.Now.ToString() #>";
	}
}

And here is the output:

public class HelloWorld
{
	public string GetTime()
	{
		return "01/04/2009 16:05:59";
	}
}

Note that the DateTime.Now.ToString() has been evaluated by the template engine, resulting in a string literal in the generated file. For an excellent and detailed overview of T4 templates I would recommend heading over to Oleg Sych’s blog where he has a whole host of articles on T4 templates.

Now, how do we add generated DPs to a class? Fortunately this is a problem that has been solved before, and the answer is partial classes. In the same way that your XAML editor (and DataSet editor, ASP.NET editor …) creates a partial class, we can create a partial class which just contains our DP declarations. A suitable template might look something like this:

public partial class <#= className #> 
{
<#
foreach(var dp in dps)
{
	string propertyName = dp.Name;
	string propertyType = dp.Type;
	string defaultValue = dp.DefaultValue;
	#>
	
	#region <#= propertyName #>		
			
	public <#= propertyType #> <#= propertyName #>
        {
            get { return (<#= propertyType #>)GetValue(<#= propertyName #>Property); }			
            set { SetValue(<#= propertyName #>Property, value); }
        }            
    
        public static readonly DependencyProperty <#= propertyName #>Property =
            DependencyProperty.Register("<#= propertyName #>", typeof(<#= propertyType #>),
            typeof(<#= className #>), new PropertyMetadata(<#= defaultValue #>));
        
        #endregion   
<#
} // end foreach dps
#>
}

The next problem is how to specif the DPs in a concise and simple manner. I decided that the simplest approach would be to have a single XML fie within the project which specifies all the generated classes and their DPs. For this purpose I created an XML schema (which is found in the sourcecode zip file and at the end of this post). Here is an example instance document which details a class and its DPs:

<?xml version="1.0" encoding="utf-8" ?>
<dependencyObjects
  xmlns="http://www.scottlogic.co.uk/DependencyObject"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 
  <dependencyObject type="SilverlightTemplates.RangeControl"
                    base="UserControl" notifyPropertyChanged="true" >
    <dependencyProperty type="double" defaultValue="0.0"
                        name="Maximum" propertyChangedCallback="true"/>
    <dependencyProperty type="double" defaultValue="0.0"
                        name="Minimum" propertyChangedCallback="true"/>
  </dependencyObject>
 
</dependencyObjects>

The XML schema serves two purposes, firstly Visual Studio will auto-complete making the construction of this document a breeze, secondly, ensuring that the document is valid means that the template itself does not have to be programmed in such a ‘defensive’ style.

Notice also a few other goodies here, the propertyChangedCallback attribute indicates that a property changed event handler will be added to the code as a partial method. Furthermore, the notifyPropertyChanged attribute indicates that the class will implemented INotifypropertyChanged, raising the PropertyChanged event whenever a DP changes. More boiler-plate code eradicated!

The complete template that builds classes from the XML file contains a class feature block (for details see Oleg’s blog), called GenerateClass, which takes two parameters. The first is the fully qualified name of the class, the second is the location of the XML file:

<#@ include file="DependencyObjectTemplate.tt" #>
<#
	GenerateClass("SilverlightTemplates.RangeControl",
		@"C:\Projects\Visual Studio\ ... \SilverlightTemplates\MyTemplate.xml");
#>

Unfortunately, the when code templates are executed their working directory is not the location of the template file itself. This explains the use of the absolute file path in the above example. Here is the file generated from the above XML:

 
using System;
using System.Windows;
using System.Windows.Controls;
using System.ComponentModel;
 
namespace SilverlightTemplates
{
    public partial class RangeControl : UserControl, INotifyPropertyChanged
    {
 
        #region Maximum
 
        public double Maximum
        {
            get { return (double)GetValue(MaximumProperty); }
            set { SetValue(MaximumProperty, value); }
        }
 
        public static readonly DependencyProperty MaximumProperty =
            DependencyProperty.Register("Maximum", typeof(double),
            typeof(RangeControl), new PropertyMetadata(0.0, OnMaximumPropertyChanged));
 
 
        private static void OnMaximumPropertyChanged(DependencyObject d,
            DependencyPropertyChangedEventArgs e)
        {
            RangeControl myClass = d as RangeControl;
            myClass.OnPropertyChanged("Maximum");
            myClass.OnMaximumPropertyChanged(e);
        }
 
        partial void OnMaximumPropertyChanged(DependencyPropertyChangedEventArgs e);
 
        #endregion
 
        #region Minimum
 
        public double Minimum
        {
            get { return (double)GetValue(MinimumProperty); }
            set { SetValue(MinimumProperty, value); }
        }
 
        public static readonly DependencyProperty MinimumProperty =
            DependencyProperty.Register("Minimum", typeof(double),
            typeof(RangeControl), new PropertyMetadata(0.0, OnMinimumPropertyChanged));
 
 
        private static void OnMinimumPropertyChanged(DependencyObject d,
            DependencyPropertyChangedEventArgs e)
        {
            RangeControl myClass = d as RangeControl;
            myClass.OnPropertyChanged("Minimum");
            myClass.OnMinimumPropertyChanged(e);
        }
 
        partial void OnMinimumPropertyChanged(DependencyPropertyChangedEventArgs e);
 
        #endregion
 
 
        #region INotifyPropertyChanged Members
 
        public event PropertyChangedEventHandler PropertyChanged;
 
        protected void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
 
        #endregion
 
    }
}

So much code, from such a small XML file!

I have created a simple example project with a user control which contains a pair of DPs, which you can download: silverlighttemplate.zip.

If you find this template useful, please let me know. Also if you find any mistakes or think of a clever way to extend it further, give me a shout.

Regards, Colin E.

APPENDIX

T4 template

Note: the T4 template engine is executed under the same environment as the project itself. Therefore, when developing Silverlight, the T4 engine code is not available, hence we reference the required DLLs explicitly.

<#@ output extension="cs" #>
<#@ template language="C#v3.5" #>
<#@ assembly name="C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\System.dll" #>
<#@ assembly name="C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5\System.Core.dll" #>
<#@ assembly name="C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5\System.Xml.Linq.dll" #>
<#@ assembly name="C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\System.Xml.dll" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Xml.Linq" #>
<#+

private void GenerateClass(string classFullName, string xmlFileLocation)
{
    string classNamespace = classFullName.Substring(0, classFullName.LastIndexOf('.'));
    string className = classFullName.Substring(classFullName.LastIndexOf('.') + 1);
    
    XNamespace ns = "http://www.scottlogic.co.uk/DependencyObject";
	XDocument xmlFile = XDocument.Load(xmlFileLocation);

	var dps =	from dp in xmlFile.Descendants(ns + "dependencyProperty")
				where dp.Parent.Attribute("type").Value == classFullName
				select dp;
	
	
	var depObj = (from c in xmlFile.Descendants(ns + "dependencyObject")
					where c.Attribute("type").Value == classFullName
					select c).Single();		
				
	bool classRaisesPropertyChanged = depObj.Attribute("notifyPropertyChanged")!=null &&
			(depObj.Attribute("notifyPropertyChanged").Value == "1" || depObj.Attribute("notifyPropertyChanged").Value == "true");
			
	string baseType = depObj.Attribute("base").Value;
#>
using System;
using System.Windows;
using System.Windows.Controls;
using System.ComponentModel;

namespace <#= classNamespace #>
{
	public partial class <#= className #> : <#= baseType #><#+ if(classRaisesPropertyChanged){ #>, INotifyPropertyChanged<#+ } #> 
	{
<#+
	foreach(var dp in dps)
	{
		string propertyName = dp.Attribute("name").Value;
		string propertyType = dp.Attribute("type").Value;
		string defaultValue = dp.Attribute("defaultValue").Value;
		string typeConverter = dp.Attribute("typeConverter")!=null ? dp.Attribute("typeConverter").Value : null;
		bool propertyChangedCallback = dp.Attribute("propertyChangedCallback")!=null &&
			(dp.Attribute("propertyChangedCallback").Value == "1" || dp.Attribute("propertyChangedCallback").Value == "true");
		#>
		
		#region <#= propertyName #>		
		<#+
		if (typeConverter!=null)
		{
		#> 
		[TypeConverter(<#= typeConverter #>)]
		<#+
		}
		#> 	
		public <#= propertyType #> <#= propertyName #>
        {
            get { return (<#= propertyType #>)GetValue(<#= propertyName #>Property); }			
            set { SetValue(<#= propertyName #>Property, value); }
        }            
        <#+
        if (!propertyChangedCallback && !classRaisesPropertyChanged)
		{
        #>
        
        public static readonly DependencyProperty <#= propertyName #>Property =
            DependencyProperty.Register("<#= propertyName #>", typeof(<#= propertyType #>),
            typeof(<#= className #>), new PropertyMetadata(<#= defaultValue #>));
            
        <#+
		}
		else
		{
		#>
		
		public static readonly DependencyProperty <#= propertyName #>Property =
            DependencyProperty.Register("<#= propertyName #>", typeof(<#= propertyType #>),
            typeof(<#= className #>), new PropertyMetadata(<#= defaultValue #>, On<#= propertyName #>PropertyChanged));
		
		
		private static void On<#= propertyName #>PropertyChanged(DependencyObject d,
            DependencyPropertyChangedEventArgs e)
        {        
			<#= className #> myClass = d as <#= className #>;
			myClass.OnPropertyChanged("<#= propertyName #>");
			myClass.On<#= propertyName #>PropertyChanged(e);			
        }
        
        partial void On<#= propertyName #>PropertyChanged(DependencyPropertyChangedEventArgs e);        
		<#+
		} // end else if (!propertyChangedCallback && !classRaisesPropertyChanged)
		#> 
        #endregion     
	<#+
	} // end foreach dps

	if (classRaisesPropertyChanged)
	{
	#>	
	
		#region INotifyPropertyChanged Members

		public event PropertyChangedEventHandler PropertyChanged;

		protected void OnPropertyChanged(string propertyName)
		{
			if (PropertyChanged != null)
			{
				PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
			}
		}

		#endregion
	<#+
	}
	#>	
	}
}

<#+	
}
#>

The XML Schema

<?xml version="1.0" encoding="utf-8"?>
<xs:schema
    targetNamespace="http://www.scottlogic.co.uk/DependencyObject"
    elementFormDefault="qualified"
    xmlns="http://www.scottlogic.co.uk/DependencyObject"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">
 
  <xs:element name="dependencyObjects" type="dependencyObjectsType"/>
 
  <xs:complexType name="dependencyObjectsType">
    <xs:sequence>
      <xs:element name="dependencyObject" type="dependencyObjectType"  maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>
 
  <xs:complexType name="dependencyObjectType">
    <xs:sequence>
      <xs:element name="dependencyProperty" type="dependencyPropertyType" maxOccurs="unbounded"/>
    </xs:sequence>
    <xs:attribute name="type"/>
    <xs:attribute name="notifyPropertyChanged" type="xs:boolean" use="optional"/>
    <xs:attribute name="base" type="xs:string" use="required"/>
  </xs:complexType>
 
  <xs:complexType name="dependencyPropertyType">
    <xs:attribute name="name" type="xs:string" use="required"/>
    <xs:attribute name="type" type="xs:string" use="required"/>
    <xs:attribute name="typeConverter" type="xs:string" use="optional"/>
    <xs:attribute name="defaultValue" type="xs:string" use="required"/>
    <xs:attribute name="propertyChangedCallback" type="xs:boolean" use="optional"/>
    <xs:attribute name="notifyPropertyChanged" type="xs:boolean" use="optional"/>
  </xs:complexType>
 
</xs:schema>