1

I am watching an online video tutorial about DataTemplates

The demo code is the follows

    <StackPanel.Resources>
        <ControlTemplate x:Key="MyButton">
            <Grid>
                <Ellipse Fill="{TemplateBinding Background}" />
                <ContentControl Content="{TemplateBinding ContentControl.Content}" /><!--why this-->
            </Grid>                
        </ControlTemplate>
    </StackPanel.Resources>

    <Button Content="Click me" Background="Green" Width="100" Height="50" Template="{StaticResource MyButton}" />
</StackPanel>

The bit where I'm lost is

<ContentControl Content="{TemplateBinding ContentControl.Content}" />

Why is it ControlControl.Content and not just Content. If we review the line of code before this it shows Ellipse Fill="{TemplateBinding Background}" and not <Ellipse Fill="{TemplateBinding Ellipse.Background}" />

Why do we state ContentControl? Is it because the property Content of the Button is actually an object of type ContentControl where as Background is just a string property of Button?

MyDaftQuestions
  • 4,487
  • 17
  • 63
  • 120
  • 2
    in `ControlTemplate` add `TargetType="{x:Type Button}"` otherwise template does not know target type – dkozl Feb 20 '15 at 14:08
  • @dkozl, I believe you, you've helped me lots in the past so I'm not being rude asking this, but why? As it is, it runs fine. Is this more about explicit coding or could there be gotcha's without defining it? – MyDaftQuestions Feb 20 '15 at 14:12
  • @dkozl, I tested it - by explicity typing the type, I don't need ContentControl... I guess because it knows the type, it knows what properties it has... WIthout it, I guess it only has access to object (or control or framework element - whatever it inherits from). This can easily be the answer if you want to type it up? – MyDaftQuestions Feb 20 '15 at 14:14
  • 1
    Basically if you don't specify `TargetType` it's like you would have specified it for `Control` type which does not define `Content` property for example so you have to specify containing type. For more info look for example [here](http://stackoverflow.com/questions/3632181/wpf-controltemplates-must-have-targettype-or-not) – dkozl Feb 20 '15 at 14:16

1 Answers1

2

If you specify the type of the ControlTemplate (also the same for Style), then the compiler will know what object to look at to find the Content property:

<ControlTemplate x:Key="MyButton" TargetType="{x:Type Button}">
    <Grid>
        <Ellipse Fill="{TemplateBinding Background}" />
            <ContentControl Content="{TemplateBinding Content}" />
    </Grid>                
</ControlTemplate>

If you don't specify the type, the compiler will require you to enter the type in the TemplateBinding path as you have.

However, sometimes you can also specify which base class a property is from as in this case, because the Content property is actually inherited in the Button Class from the ContentControl class... you can see this by clicking on the Content property in the Button Class page on MSDN, which will take you to the ContentControl.Content Property page.

You should find that in this case, you could also use Button.Content as the property is inherited in the Button Class. Therefore, to answer your question, you don't actually need to use ContentControl.Content... you have a choice.


UPDATE >>>

You can do that with Styles, but with ControlTemplates, you'd have to make sure that the objects that you apply it to also have the same base class and all properties used in the ControlTemplate. Theoretically, you could then do this:

<ControlTemplate x:Key="MyButton" TargetType="{x:Type ContentControl}">
    <Grid>
        <Ellipse Fill="{TemplateBinding Background}" />
        <ContentControl Content="{TemplateBinding Content}" />
    </Grid>
</ControlTemplate>

...

 <RadioButton Template="{StaticResource MyButton}" Content="Hey" />

However, I imagine that you actually need to use a ContentPresenter instead of the ContentControl:

<ControlTemplate x:Key="MyButton" TargetType="{x:Type ContentControl}">
    <Grid>
        <Ellipse Fill="{TemplateBinding Background}" />
        <ContentPresenter />
    </Grid>
</ControlTemplate>

You may also like to read the What's the difference between ContentControl and ContentPresenter? page here on Stack Overflow.

Community
  • 1
  • 1
Sheridan
  • 68,826
  • 24
  • 143
  • 183
  • If I enter the target type as a base class (such as Control) then I assume I could use it for more controls. EG, If my style only changed the Cursor then it can be shared by all controls which inherit from Control? Is this correct? – MyDaftQuestions Feb 20 '15 at 14:47