Presenting content

In WPF, there is a special element that is essential but often little understood. The ContentPresenter class basically presents content, as its name suggests. It is actually used internally within ContentControl objects to present their content.

That is its sole job and it should not be used for other purposes. The only time that we should declare these elements is within a ControlTemplate of a ContentControl element or one of its many derived classes. In these cases, we declare them where we want the actual content to appear.

Note that specifying the TargetType property on a ControlTemplate when using a ContentPresenter will result in its Content property being implicitly data bound to the Content property of the relevant ContentControl element. We are however free to data bind it explicitly to whatever we like:

<ControlTemplate x:Key="ButtonTemplate" TargetType="{x:Type Button}"> 
  <ContentPresenter Content="{TemplateBinding ToolTip}" /> 
</ControlTemplate> 

The ContentTemplate and ContentTemplateSelector properties both mirror those of the ContentControl class and also enable us to select a DataTemplate based upon a custom condition. Like the Content property, both of these properties will also be implicitly data bound to the properties of the same names in the templated parent if the TargetType property of the ControlTemplate has been set.

This usually saves us from having to explicitly data bind these properties, although there are a few controls where the names of the relevant properties do not match up. In these cases, we can use the ContentSource property as a shortcut to data bind the Content, ContentTemplate, and ContentTemplateSelector properties.

If we set this property to Header, for example, the Framework will look for a property named Header on the ContentControl object to implicitly data bind to the Content property of the presenter. Likewise, it will look for properties named HeaderTemplate and HeaderTemplateSelector to implicitly data bind to the ContentTemplate and ContentTemplateSelector properties.

This is primarily used in a ControlTemplate for a HeaderedContentControl element or one of its derived classes:

<ControlTemplate x:Key="TabItemTemplate" TargetType="{x:Type TabItem}"> 
  <StackPanel> 
    <ContentPresenter ContentSource="Header" /> 
    <ContentPresenter ContentSource="Content" /> 
  </StackPanel> 
</ControlTemplate> 

There are specific rules that determine what the ContentPresenter will display. If the ContentTemplate or ContentTemplateSelector property is set, then the data object specified by the Content property will have the resulting data template applied to it. Likewise, if a data template of the relevant type is found within the scope of the ContentPresenter element, it will be applied.

If the content object is a UI element, or one is returned from a type converter, then the element is displayed directly. If the object is a string, or a string is returned from a type converter, then it will be set as the Text property of a TextBlock control and that will be displayed. Likewise, all other objects simply have the ToString method called on them and then this output is rendered in a standard TextBlock at runtime.