The following is similar to what I'm trying to accomplish. However, I get the error
Invalid PropertyDescriptor value.
on the Template Setter. I suspect it's because I didn't specify a TargetType for the Style; however, I don't know the container type for ItemsControl.
<ItemsControl>
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<StackPanel>
<TextBlock Text="Some Content Here" />
<ContentPresenter />
<Button Content="Edit" />
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ItemsControl.ItemContainerStyle>
<!-- heterogenous controls -->
<ItemsControl.Items>
<Button Content="Content 1" />
<TextBox Text="Content 2" />
<Label Content="Content 3" />
</ItemsControl.Items>
</ItemsControl>
You can qualify the property name with the type name:
The container for
ItemsControlis normally aContentPresenter, but if the child is aUIElementthen it won't use a container. In this case, all of the children are Controls, so theItemContainerStylewill apply to them directly. If you added an item other than aUIElement, that setter would set theControl.Templateproperty on theContentPresenter, which would succeed but have no effect.Actually, it sounds like what you want is to wrap each child in a container, even if they are already a
UIElement. To do that, you will have to use a subclass ofItemsControl. You could use an existing one likeListBox, or you could subclassItemsControland overrideGetContainerForItemOverrideandIsItemItsOwnContainerOverrideto wrap the items in your own container. You could wrap them in aContentControland then use that as theTargetTypefor theStyle.You will also need to set the
TargetTypeon theControlTemplateso that theContentPresenterwill bind to theContentproperty: