Insert DataGrid in WPView TreeView Nodes

I need to display a hierarchy in a treeview . But the details should be displayed in the datagrid .

How I'd like it to be

How can I write my own template for this? I misunderstand something in the templates.

<TreeView ItemsSource="{Binding Path=Categories}"> <TreeView.Resources> <HierarchicalDataTemplate DataType="{x:Type stackProjects:Category}" ItemsSource="{Binding Path=SubCategories}"> <TextBlock Margin="3" Text="{Binding Path=CategoryName}"/> </HierarchicalDataTemplate> <HierarchicalDataTemplate DataType="{x:Type stackProjects:SubCategory}" ItemsSource="{Binding Path=Details}"> <TextBlock Text="{Binding Path=SubCategoryName}"/> </HierarchicalDataTemplate> <DataTemplate DataType="{x:Type stackProjects:Detail}" > <StackPanel Orientation="Horizontal"> <TextBlock Margin="3" Text="{Binding Path=Name}"/> <TextBlock Margin="3" Text=" - "/> <TextBlock Margin="3" Text="{Binding Path=Info}"/> </StackPanel> </DataTemplate> </TreeView.Resources> </TreeView> 
+4
source share
1 answer

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; //returned value should be IEnumerable with one element. //Otherwise we will not see children nodes return new List<IItemsWrapper> {instance}; } return null; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } } 

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:

DataGrid for TreeView nodes

+8
source

All Articles