This blog post examines the difference between how DataTemplates and Styles are applied to instances of related classes. In a nutshell, typed DataTemplates support polymorphism while typed Styles do not.
If you create a DataTemplate where its DataType property is set to a base type it will be used to render an instance of a class which derives from the base type. In that sense, DataTemplates support polymorphism. Of course, if you also have another DataTemplate which specifically targets the subclass then that template will be used instead.
On the other hand, a typed Style (i.e. a Style with no x:Key) whose TargetType is set to the base type will not be applied to elements of the derived type. Styles do not support polymorphism. For a typed Style to be applied to an object, the Style’s TargetType must exactly match the type of the object.
[EDIT: As Jan Kucera keenly pointed out in a comment below, if you give an x:Key to a Style which targets a base type and then assign that Style to an instance of a subclass’s Style property, the Style will be applied to the subclass instance. This means that there seems to be an inconsistency as to how Styles are applied “polymorphically.” It works if you apply them explicitly to an element, but a typed Style will not be applied to a subclass of its TargetType.]
I was not aware of this difference until recently. I spent quite a while tracking down what was rendering a particular data object, and eventually realized that the template I was looking for had its DataType set to a base class of the object being displayed. After realizing that DataTemplates support polymorphism I tested if Styles do as well, and discovered that they do not.
I think the best way to convey this difference is by showing a simple example. Here are the classes used in the demo app:
Here is the XAML which creates an instance of Foo2 and Button2, and applies a template and style to them:
If you run the demo application with the XAML seen above, the UI looks like this:
As you can see based on the XAML seen previously, the Button2 instance is not affected by the Style which targets the Button class. However, the Foo2 object is rendered by the DataTemplate whose DataType is set to the Foo base class.
If we were to uncomment the additional DataTemplate and Style seen in the XAML above, the UI would look like this:
The Button2 and Foo2 are colored red in this situation because the presence of a DataTemplate and Style specific to those types are present at runtime.
You can download the demo app here: Templates Styles and Polymorphism (demo app) Be sure to change the file extension from .DOC to .ZIP and then decompress it.