Jeff Wain
Jeff Wain

Reputation: 1022

Nested DataTemplates in ListBox

Is there any way to make a DataTemplate reference itself just from XAML? In this particular case trying to reference a DataTemplate from a ListBox contained within the same DataTemplate. Here is the solution I'd like, which doesn't work.

  <DataTemplate x:Key="nestedItem" DataType="{x:Type local:NestedItem}">
    <Expander Header="{Binding Path=Name}">
      <ListBox ItemsSource="{Binding Path=Items}" x:Name="itemsList"
        ItemTemplate="{StaticResource nestedItem}"/>
    </Expander>
  </DataTemplate>

And here's the solution I am currently using, which works.

  <DataTemplate x:Key="nestedItem" DataType="{x:Type local:NestedItem}">
    <Expander Header="{Binding Path=Name}" Expanded="OnItemExpanded">
      <ListBox ItemsSource="{Binding Path=Items}" x:Name="itemsList"/>
    </Expander>
  </DataTemplate>

With code behind:

private void OnItemExpanded(object sender, RoutedEventArgs e)
  {
    if (e.OriginalSource != sender) return;
    var source = (Expander) sender;
    ListBox listBox = source.FindName("itemsList") as ListBox;
    NestedItem item = source.DataContext as NestedItem;
    listBox.ItemsSource = item.Items;
    listBox.ItemTemplate = (DataTemplate) FindResource("nestedItem");
  }

Upvotes: 2

Views: 3932

Answers (2)

Simon D.
Simon D.

Reputation: 4481

Did you try using HierarchicalDataTemplate instead of DataTemplate for your first solution? Did not test it for your case, but for treeviews it usually works that way.

Upvotes: 0

rmoore
rmoore

Reputation: 15393

If you change your inner reference to be a DynamicResource instead of a StaticResource then it will work as you want. This is because there are some differences in how a StaticResource and DynamicResource actually look for the Resource item.

<DataTemplate x:Key="Local_NestedItem"
              DataType="{x:Type local:NestedItem}">
    <Expander Header="{Binding Path=Name}">
        <ListBox ItemsSource="{Binding Path=Items}"
            x:Name="itemsList"
            ItemTemplate="{DynamicResource Local_NestedItem}" />
    </Expander>
</DataTemplate>

Also, if you don't mind using some code, another good option is to use a DataTemplateSelector

Upvotes: 3

Related Questions