HierarchicalDataTemplate -- Recursive Avalon Data Binding

I just discovered the HierarchicalDataTemplate, which is basically a DataTemplate that can recursively walk a tree. Once again, I'm blown away by how Avalon databinding works. The HierarchicalDataTemplate derives from DataTemplate, but adds an ItemsSource property, which basically is a way to tell the template where to look for its children.  Combine this with the Treeview control, XML and some XPath syntax and you've cooked up a very handy visualization.  It is similar to programming XSLT with templates and matching, in that you can wire up more than one DataTemplate or HierarchicalDataTemplate and the databinding engine will attempt to match a template based on its DataType.  When using XML, the DataType corresponds to an element name; when using an ObjectDataProvider, the DataType will match on a CLR type name.  Perhaps the nicest feature of using templates in a treeview is that the template itself can contain any Avalon visual tree, so that the nodes of your tree can be much more sophisticated than just text.  And the nodes can change depending on the type of object or element they are bound to.

Here's a super simple sample, without anything fancy wired up:

<Canvas xmlns="https://schemas.microsoft.com/winfx/avalon/2005" xmlns:x="https://schemas.microsoft.com/winfx/xaml/2005">
<Canvas.Resources>
<XmlDataProvider x:Key="FamilyTree" XPath="*">
<Reporting xmlns="">
<Person Name="Steve">
<Person Name="Lisa" >
<Person Name="Mary" />
<Animal Name="Dog" >
<Person Name="Bill" />
</Animal >
<Animal Name="Cat" />
<Insect Name="Ant">
<Animal Name="Deer" />
<Animal Name="Horse" />
</Insect>
<Person Name="John" />
</Person>
</Person>
</Reporting>
</XmlDataProvider>
<HierarchicalDataTemplate DataType="Person" ItemsSource ="{Binding XPath=*}">
<TextBlock Text="{Binding XPath=@Name}" />
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="Animal" ItemsSource ="{Binding XPath=*}">
<TextBlock Text="{Binding XPath=@Name}" FontSize="20"/>
</HierarchicalDataTemplate>
<DataTemplate DataType="Insect" >
<TextBlock Text="{Binding XPath=@Name}" />
</DataTemplate>
</Canvas.Resources>
<StackPanel>
<TreeView ItemsSource="{Binding Source={StaticResource FamilyTree}, XPath=*}"/>
</StackPanel>
</Canvas>

You can see how having multiple templates restyles the "Animal" nodes differently than the "Person" nodes.   For my ItemsSource on the templates, I just specify an XPath asterisk, so that it always looks at all children.  The "Insect" element is in just a DataTemplate, so the engine won't dig into its children and thus they are not in the treeview's output.

I've only scratched the surface with this; you can imagine all kinds of scenarios where this type of functionality could be very powerful and productive as far as minimal code and extreme customization.

By the way, if you are interested in databinding and collections and whatnot, check out Bea Costa's blog, which has a number of very nice samples and explanations.