Search code examples
c#wpfbindinghierarchicaldatatemplateobjectdataprovider

Using ObjectDataProvider inside HierarchicalDataTemplate


I want to add items of my class treeviewitem to a TreeView.

And I want to bind the ItemSource of this TreeViewItem to a method of itself !

I am trying to use the ObjectDataProvider for this.. See my XAML:

<Grid Background="#FFE5E5E5">
    <Grid.Resources>
        <HierarchicalDataTemplate DataType="{x:Type myNs:treeviewitem}">
            <HierarchicalDataTemplate.Resources>
                <ObjectDataProvider x:Key="getItems"
                                    MethodName="GetItems"
                                    ObjectInstance="{Binding RelativeSource={RelativeSource Self}}" />
            </HierarchicalDataTemplate.Resources>
            <HierarchicalDataTemplate.ItemsSource>
                <Binding Source="{StaticResource getItems}" />
            </HierarchicalDataTemplate.ItemsSource>
            <StackPanel Orientation="Horizontal">
                <TextBlock Margin="5,0,0,0"
                           Text="{Binding Name}" />
            </StackPanel>
        </HierarchicalDataTemplate>
    </Grid.Resources>
    <TreeView x:Name="guiTreeview"
              HorizontalAlignment="Left"
              Width="200" />
</Grid>

But binding to an ObjectInstance isnt possible!

How is it possible to get the current object instance "into" the ObjectDataProvider?

What would be the right way of doint this?

And NO, its not possible to use a Property ..


Solution

  • I have done it now with a ValueConverter.

    XAML:

    <Grid Background="#FFE5E5E5">
        <Grid.Resources>
            <HierarchicalDataTemplate DataType="{x:Type myNs:MyItem}" ItemsSource="{Binding RelativeSource={RelativeSource Self}, Converter={myNs:GetItemsConverter}}" >
                <StackPanel Orientation="Horizontal">
                    <TextBlock Margin="5,0,0,0" Text="{Binding Name}" />
                </StackPanel>
            </HierarchicalDataTemplate>
    
        </Grid.Resources>
        <TreeView x:Name="guiTreeview" HorizontalAlignment="Left" Width="200" />
    
    </Grid>
    

    Converter:

    public abstract class BaseConverter : MarkupExtension
    {
        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            return this;
        }
    }
    
    public class GetItemsConverter : BaseConverter, IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            var tvi = value as TreeViewItem;
            if (tvi == null) return null;
    
            var myitem = tvi.DataContext as MyItem;
            if (myitem == null) return null;
    
            return myitem.GetItems();
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return null;
        }
    }