Есть ли способ сделать ссылку DataTemplate непосредственно из XAML? В этом конкретном случае вы пытаетесь ссылаться на DataTemplate из ListBox, содержащегося в том же DataTemplate. Вот решение, которое я бы хотел, что не работает.
<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>
И вот решение, которое я сейчас использую, которое работает.
<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>
С кодом позади:
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");
}
Если вы измените свою внутреннюю ссылку как DynamicResource вместо StaticResource, тогда она будет работать так, как вы хотите. Это связано с тем, что есть некоторые отличия в том, как StaticResource и DynamicResource действительно ищут элемент Resource.
<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>
Кроме того, если вы не против использования какого-либо кода, другой хороший вариант - использовать DataTemplateSelector
Вы пытались использовать HierarchicalDataTemplate вместо DataTemplate для своего первого решения? Не тестировал его для вашего дела, но для древовидных изображений он обычно работает именно так.