Search code examples
wpfcontroltemplatecontentpresenter

ContentPresenter within ControlTemplate cannot change attached dependency property


Why does the following simplified code not sets the font-size of the TextBlock to 50?

<Window.Resources>
    <ControlTemplate TargetType="ContentControl" x:Key="Test">
        <ContentPresenter TextBlock.FontSize="50" />
    </ControlTemplate>        
</Window.Resources>        
<Grid>
    <ContentControl Template="{StaticResource Test}">
        <TextBlock>Test should be rendered big</TextBlock>
    </ContentControl>                   
</Grid>

If I change the value of the FontSize property, visual studio shows me the text in the size I want. After compiling or executing the app, the size of the textblock is always reset to its default size.

I have also tested various versions with styles and embedded resources but I end always in the situation that I cannot set inheriting attached dp's from within a ControlTemplate that contains a ContentPresenter. Is this by design?


Solution

  • I found the reason of this behavior - it’s by design:

    If the Content of ContentControl is already a WPF-Element, it is created before using it in the ContenPresenter. The logical parent of the element is therefore ContentControl. I can check this through changing the ContentControl-markup to the following:

    <ContentControl Template="{StaticResource Test}" TextBlock.FontSize="50">                
        <TextBlock>
                This text now is shown with a size of 50
        </TextBlock>                    
    </ContentControl>
    

    In this example the text size is 50 as desired. I can prove this argumentation also with wpf-visualizer of visual studio. The parent is ContentControl and through dp-inheritance, the FontSize is taken from the parent (ContentControl), and the text is shown with a size of 50!

    Another behavior can be observed if the ContentControl contains only text as content:

    <Window.Resources>
        <ControlTemplate x:Key="Test"  TargetType="{x:Type ContentControl}">
            <ContentPresenter  TextBlock.FontSize="50"/>
        </ControlTemplate>
    </Window.Resources>                
    <Grid>
        <ContentControl Template="{StaticResource Test}">                
            This text is shown with a size of 50
        </ContentControl>
    </Grid>
    

    In this scenario, the TextBox is created through the ContentPresenter because text cannot be entered in the visual tree. The textbox has no parent but the TemplateParent-property leads to the ContentPresenter as the TextBoxes parent and the DP-system takes the FontSize-value through attached dependency property inheritance from the ContentPresenter. That’s why in this scenario the font size is changed to 50.

    The different scenarios are described here.

    What I don’t understand is, why VS2010 shows the FontSize 50 before compiling.