Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

does HierarchicalDataTemplate.Triggers support conditional binding to ItemsSource and ItemTemplate?

Tags:

c#

wpf

xaml

The following xaml generates compile time error: Cannot find the Template Property 'ItemsSource' on the type 'System.Windows.Controls.ContentPresenter'

    <HierarchicalDataTemplate x:Key="tvTemplate">
        <TextBlock Text="{Binding Path=Name}"/>
        <HierarchicalDataTemplate.Triggers>
            <DataTrigger Binding="{Binding HasSubCat1}" Value="True">
                <Setter Property="ItemsSource" Value="{Binding SubCategories1}" />
                <Setter Property="ItemTemplate" Value="{Binding subCat1Template}" />
            </DataTrigger>
            <DataTrigger Binding="{Binding HasSubCat1}" Value="False">
                <Setter Property="ItemsSource" Value="{Binding SubCategories2}" />
                <Setter Property="ItemTemplate" Value="{Binding subCat2Template}" />
            </DataTrigger>
        </HierarchicalDataTemplate.Triggers>
    </HierarchicalDataTemplate>
</UserControl.Resources>

Basically, i have data that when displayed will be two levels or three levels deep...the type of data objects will differ depending with it is destined to be part of the 2 or 3 level branch. This is why i need to conditionally set the template and items source. can this be done

like image 396
mike01010 Avatar asked Sep 02 '25 10:09

mike01010


1 Answers

Not quite sure from your description exactly what your data looks like but I think what you want is different HierarchicalDataTemplates with a DataTemplateSelector to choose between them at each item. The selector just needs to switch between the templates depending on some value on the data item, like what your DataTriggers are trying to do:

public class CategoryTemplateSelector : DataTemplateSelector
{
    public DataTemplate Cat1Template { get; set; }
    public DataTemplate Cat2Template { get; set; }

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        return ((CategoryBase)item).HasSubCat1 ? Cat1Template : Cat2Template;
    }
}

You then need 2 simple templates, each with a different ItemsSource binding:

<HierarchicalDataTemplate x:Key="tvTemplate1" ItemsSource="{Binding SubCategories1}">
    <TextBlock Text="{Binding Path=Name}"/>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate x:Key="tvTemplate2" ItemsSource="{Binding SubCategories2}">
    <TextBlock Text="{Binding Path=Name}"/>
</HierarchicalDataTemplate>

And then on your TreeView, instead of setting the ItemTemplate, use the selector:

<TreeView.ItemTemplateSelector>
    <local:CategoryTemplateSelector Cat1Template="{StaticResource tvTemplate1}" Cat2Template="{StaticResource tvTemplate2}"/>
</TreeView.ItemTemplateSelector>
like image 140
John Bowen Avatar answered Sep 03 '25 23:09

John Bowen