Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DataTemplate vs ItemContainerTemplate

Tags:

wpf

xaml

What is ItemContainerTemplate used for? It is derived from DataTemplate, but I don't see any difference between them except the ItemContainerTemplateKey property. When should I use one and when the other?

like image 794
andreas Avatar asked May 23 '14 08:05

andreas


3 Answers

The ItemContainerTemplate describes the world around your Item. For example in a ListBox the selection rectangle around your ListBoxItem. The DataTemplate describes how you ListBoxItem apears and of which elements it consists.

Dr. WPF did a good example: http://drwpf.com/blog/category/item-containers/

like image 20
Albi Avatar answered Nov 10 '22 18:11

Albi


The only difference between DataTemplate and ItemContainerTemplate is the way the resource dictionary key is automatically provided (assuming it is not set explicitly). Namely, DataTemplate is decorated with [DictionaryKeyProperty("DataTemplateKey")] attribute, and the DataTemplateKey is basically defined as:

public object DataTemplateKey
{
    get { return (DataType != null) ? new DataTemplateKey(DataType) : null; 
}

See DataTemplate source for reference.

ItemContainerTemplate derives from DataTemplate, but is decorated with [DictionaryKeyProperty("ItemContainerTemplateKey")] attribute (which in practice replaces the inherited one), and ItemContainerTemplateKey property is defined as follows:

public object ItemContainerTemplateKey
{
    get { return (DataType != null) ? new ItemContainerTemplateKey(DataType) : null; }
}

See ItemContainerTemplate source for reference.

The difference seems small - DataTemplate returns an instance of DataTemplateKey and ItemContainerTemplate returns an instance of ItemContainerTemplateKey (both derive from TemplateKey). So basically these two are equivalent1:

<ItemContainerTemplate DataType="{x:Type sys:String}" />
<DataTemplate x:Key="{ItemContainerTemplateKey {x:Type sys:String}}" />

and so are these:

<ItemContainerTemplate x:Key="{DataTemplateKey {x:Type sys:String}}" />
<DataTemplate DataType="{x:Type sys:String}" />

The main practical difference between these two is that DataTemplate with default key is treated as an implicit template2, whereas ItemContainerTemplate is not. In fact, you need to manually reference it, e.g.:

<ListBox ItemTemplate="{StaticResource {ItemContainerTemplate {x:Type sys:String}}}" />

I'm not sure about the intentions behind creating ItemContainerTemplate class. I guess it gives you a clearer overview of the code, where you know that such a template is specifically intended to be used in an ItemsControl (or a derived control). Also, I guess it would prove to be pretty simple to write a strongly reusable DataTemplateSelector that would take advantage of this class.


1They're not equivalent in the sense that created objects are of different types, but functionally they're equivalent.

2Implicit templates are applied to all objects of corresponding type within the scope, unless a template is set explicitly.

like image 63
Grx70 Avatar answered Nov 10 '22 17:11

Grx70


You can put an ItemContainerTemplate in a ResourceDictionary, and it will automatically use the DataType as its key.

That's the only difference.

like image 1
SLaks Avatar answered Nov 10 '22 17:11

SLaks