DataGrid, binding and the case of the broken namescope

It is very common to have multiple sibling instances of a template, such as the column DataTemplates in a DataGrid. If these shared a namescope, there would be name collisions. So templates in XAML and Silverlight are obliged to have private namescopes.

The change of namescope makes it impossible, inside a DataTemplate, to use ElementName syntax to bind a Selector.ItemsSource to a DataSource defined at page level. This is a significant issue for LOB application developers. Foreign keys into lookup tables are very commonly implemented using a ComboBox with its list provided by another DataSource. Fortunately, once the nature of the problem is clearly understood it is not difficult to solve.

There are two possible approaches. Both will work. One scales better.

  • Declare the lookup DataSource in the template and use ElementName binding.
  • Declare the lookup DataSource objects as page resources and use StaticResource binding.

Declaring the lookup data source inside the template would bring it into the right name scope for ElementName binding to work. But putting the data source in the template would be a performance disaster. It would produce a private instance of the DataSource for every instance of the template.

Like name scope, resource scope is container-based. It is possible to declare a resource section in a template, but this is such an obviously bad idea – a private instance of each resource would be created for each instance of the template – that nobody ever does it. The possibility of resource name collisions is therefore unimportant, and we can use the resource namespace to work around the necessarily disjunct name scope of a template.