Using Interface as DataType for HierarchicalDataTemplate in TreeView

This can get a bit tricky if you are not careful. I ended up spending 2 hours to get this to work. Need to follow the following steps:

  1. Create a DataTemplateSelector. This basically means deriving from DataTemplateSelector class and overriding the SelectTemplate method.
  2. Add this class in resources section with a key
  3. Assign the above created resource key to ItemTemplateSelector attribute in XAML
  4. Most important, make sure that the point 3 above is done for <TreeViewItem> element and NOT for <HierarchicalDataTemplate>.

If you try to assign the ItemTemplateSelector anywhere else like inside <TreeView> element or inside <HierarchicalDataTemplate> then the worst part is that it will now show any compile time errors and during rendering, the overridden SelectTemplate() simply won’t get called and you might end up seeing just the ToString() implementation of the object which is usually the fully qualified object name

So be careful. The DataTemplateSelector class can be something like this:

public class InterfaceTemplateSelector : DataTemplateSelector
{

public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
FrameworkElement containerElement = container as FrameworkElement;

if (null == item || null == containerElement)
return base.SelectTemplate(item, container);

Type itemType = item.GetType();

IEnumerable<Type> dataTypes
= Enumerable.Repeat(itemType, 1).Concat(itemType.GetInterfaces());

DataTemplate template
= dataTypes.Select(t => new DataTemplateKey(t))
.Select(containerElement.TryFindResource)
.OfType<DataTemplate>()
.FirstOrDefault();

return template ?? base.SelectTemplate(item, container);

}
}

 

Advertisements

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s