I found a workaround. I had to understand that Details should be represented as a collection within the same element with the IEnumerable property. This may not be the best solution, but it works.
I needed to create a converter to wrap my collection in one.
public class BoxingItemsConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { var values = value as IEnumerable; var type = parameter as Type; if (values == null || type == null) return null; if (type.GetInterfaces().Any(x => x == typeof (IItemsWrapper))) { var instance = (IItemsWrapper) type.Assembly.CreateInstance(type.FullName); instance.Items = (IEnumerable) value;
Example for wrappers:
internal interface IItemsWrapper { IEnumerable Items { get; set; } } public class ItemsWrapper : IItemsWrapper { public IEnumerable Items { get; set; } } public class DetailItemsWrapper : ItemsWrapper{} public class InvoiceItemsWrapper:ItemsWrapper{}
And xaml. This will not require major changes. You just need to use the box converter and set the type to return to the converter parameter.
<TreeView ItemsSource="{Binding Path=Categories}"> <TreeView.Resources> <HierarchicalDataTemplate DataType="{x:Type wpfProj:Category}" ItemsSource="{Binding Path=SubCategories}"> <TextBlock Margin="4" Text="{Binding Path=CategoryName}"/> </HierarchicalDataTemplate> <HierarchicalDataTemplate DataType="{x:Type wpfProj:SubCategory}" ItemsSource="{Binding Path=Details, Converter={StaticResource boxingItems}, ConverterParameter={x:Type wpfProj:DetailItemsWrapper}}" > <StackPanel> <TextBlock Margin="4" Text="{Binding Path=SubCategoryName}"/> </StackPanel> </HierarchicalDataTemplate> <DataTemplate DataType="{x:Type wpfProj:DetailItemsWrapper}" > <DataGrid ItemsSource="{Binding Path=Items}"/> </DataTemplate> </TreeView.Resources> </TreeView>
I uploaded sample to dropbox. Here's what it looks like:

source share