WPF newbie and ContentPresenter solve the case of the disappearing content

This cost me a bit of time (and 9’59" of our UX Designer’s time) a few weeks back. My aim was very simple: write a WPF ControlTemplate that I could apply to certain controls and decorate their existing content. "Easy", thought WPF newbie, "I’ll use a ContentPresenter!"

My understanding of ContentPresenter at the time was that it dumps whatever is in the control’s content into that section of the template. So if I have something like this:

<Button Template="{StaticResource FancyTemplate}">Hello</Button>
<Button Template="{StaticResource FancyTemplate}">World</Button>

With this template in the resource dictionary (except preferably something pretty):

<ControlTemplate x:Key="FancyTemplate">            
    <Grid Background="{StaticResource FancyBackground}" Margin="10">
        <ContentPresenter />
    </Grid>            
</ControlTemplate>

I expected to see something like this:

But got this:

That’s right – nothing. Nada. Zilch. No content. Not so much as a vague hint of the ghastly template I so thoughtlessly dumped into this post.

So it turns out that ContentPresenter needs a little more information to be able to do its work. The easiest way to fix this was to set the TargetType on the template so our ContentPresenter knows what "content" is:

<ControlTemplate x:Key="FancyTemplate" TargetType="Button">            
    <Grid Background="{StaticResource FancyBackground}" Margin="10">
        <ContentPresenter />
    </Grid>            
</ControlTemplate>

The other option is to explicitly specify the property from which the ContentPresenter will get the content, using TemplateBinding:

<ControlTemplate x:Key="FancyTemplate">            
    <Grid Background="{StaticResource FancyBackground}" Margin="10">
        <ContentPresenter Content="{TemplateBinding Property=ContentControl.Content}" ;/>
    </Grid>            
</ControlTemplate>

Both of these options work fine. Hope this saves someone a bit of time.

Comments