The only difference between the DataTemplate and ItemContainerTemplate is how the resource dictionary key is automatically provided (provided that it is not set explicitly). Namely, the DataTemplate is decorated with the [DictionaryKeyProperty("DataTemplateKey")] attribute, and the DataTemplateKey is basically defined as:
public object DataTemplateKey { get { return (DataType != null) ? new DataTemplateKey(DataType) : null; }
See Source DataTemplate for reference.
ItemContainerTemplate comes from the DataTemplate , but is decorated with the [DictionaryKeyProperty("ItemContainerTemplateKey")] attribute (which in practice replaces the inherited one), and the ItemContainerTemplateKey property ItemContainerTemplateKey defined as follows:
public object ItemContainerTemplateKey { get { return (DataType != null) ? new ItemContainerTemplateKey(DataType) : null; } }
See ItemContainerTemplate source for help.
The difference seems small - a DataTemplate returns an instance of a DataTemplateKey and an ItemContainerTemplate returns an instance of an ItemContainerTemplateKey (both derived from a TemplateKey ). So basically these two equivalents are 1 :
<ItemContainerTemplate DataType="{x:Type sys:String}" /> <DataTemplate x:Key="{ItemContainerTemplateKey {x:Type sys:String}}" />
and so on:
<ItemContainerTemplate x:Key="{DataTemplateKey {x:Type sys:String}}" /> <DataTemplate DataType="{x:Type sys:String}" />
The practical difference between main between the two is that the DataTemplate with the default key is treated as implicit template 2, while the ItemContainerTemplate is not. In fact, you need to manually reference it, for example:
<ListBox ItemTemplate="{StaticResource {ItemContainerTemplate {x:Type sys:String}}}" />
I'm not sure about the intent of creating the ItemContainerTemplate class. I think this gives you a clearer overview of the code, where you know that such a template is specifically designed for use in an ItemsControl (or derived control). Also, I think it would be pretty simple to write a heavily reusable DataTemplateSelector to take advantage of this class.
1 They are not equivalent in the sense that the created objects have different types, but functionally they are equivalent.
2 Implicit templates are applied to all objects of the corresponding type within the scope, if the template is not installed explicitly.