Let's say I have a collection of objects of different classes. Each class has its UserControl DataTemplated in a resource file.
Now I want to use ItemsControl to display the collection, but I want an Border or Expander around each item.
I would expect something like this to work:
<ItemsControl ItemsSource="{Binding MyObjects}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Black" BorderThickness="3">
<ContentPresenter/>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
But the ContentPresenter seems to pick ItemTemplate, because I get a stack overflow.
How do I get each Item's DataTemplate inside the ItemTemplate?
Normally you might consider doing this by templating the item container. The problem is the "generic" ItemsControl
uses the ContentPresenter
as its item container. So even if you try and set a style with ItemContainerStyle
you will find you cannot supply a template because the ContentPresenter
does not support control templating (it does support data templating but no use here).
To use a templatable container you will have to derrive from ItemsControl
like in this example.
An alternative might be just to use the ListBox
control instead. Then you can just provide a custom template by setting a ListBoxItem
template via a style.
You can read more about containers here .
(With your permissen I'm adding the solution to your answer, Guge)
<ListBox ItemsSource="{Binding MyObjects}" Grid.Column="1">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border BorderBrush="Black" BorderThickness="3">
<ContentPresenter/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>