Reputation: 10203
I'm trying to apply both an ItemTemplate and ItemContainerStyle to an ItemsControl:-
<ItemsControl ItemsSource="{Binding LogEntries}"
ItemTemplate="{StaticResource itemTemplate}"
ItemContainerStyle="{StaticResource itemContainer}" />
However the ItemContainerStyle seems to be getting ignored (but it does work if I remove the ItemTemplate).
The item template is fairly complex and is used in a number of different views. In one specific view I need to change the spacing and background colour of the list items, hence why I was also trying to apply an ItemContainerStyle, which looks like this:-
<Style x:Key="itemContainer"
TargetType="ContentPresenter">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Border x:Name="itemBorder"
Margin="4,0,4,4"
Background="#666666">
<ContentPresenter Content="{Binding}" />
</Border>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
I'm a bit surprised that you can't apply both, unless I'm missing something? I assumed the ItemContainerStyle was really just a "wrapper" around the item content, regardless of whether or not the item's content is templated?
Upvotes: 5
Views: 4317
Reputation: 37
I ran into the same problem using code snippets from stackoverflow. The problem can be fixed if you let visual studio generate the default ItemContainerStyle. It is quite a long template so I just delete the parts I didn't need.
In visual studio click on the ListView in designer, in the properties windows scroll down to the miscellaneous section, then click on the down-arrow next to ItemContainerStyle, then click on convert to a new resource.
WARNING there are two very similar items on the list (ItemContainerStyle and ItemContainerStyleSelector) pick the right one. It is easy to miss if the properties window is not wide enough.
Upvotes: 0
Reputation: 69979
The ItemContainerStyle
is not a 'wrapper' for anything... it is a Style
. You can set both the Style
of the item container and the ItemTemplate
property, but your problem is caused because you are trying to set the ContentTemplate
property of the ContentPresenter
in your Style
and this is overwritten with the value of the ItemTemplate
. (See @Clemens' link in the comments section).
One way to get around this is to use a ListBox
that wraps its data items in ListBoxItem
s and to provide a value for the Template
property instead of the ContentTemplate
. (You can of course add a Style
to remove it's borders to make it look like an ItemsControl
). In this case, the ItemContainerStyle
will affect the ListBoxItem
instead. However, you must understand the difference.
The ItemContainerStyle
will affect the ListBoxItem
, whereas the ItemTemplate
is used to define the data object inside. Therefore, it is appropriate to define a Border
in the ItemContainerStyle
and define how the data looks in the ItemTemplate
. Try this:
<ListBox ItemsSource="{Binding Items}">
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Border Margin="4,0,4,4" Background="#666666">
<ContentPresenter Content="{Binding}" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Upvotes: 5