views:

131

answers:

3

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?

A: 

Hi,

How about :

<Window.Resources>
    <ControlTemplate TargetType="ContentControl"
                     x:Key="Test">
        <Border TextBlock.FontSize="50">
            <ContentPresenter />
        </Border>
    </ControlTemplate>
</Window.Resources>
<Grid>
    <ContentControl Template="{StaticResource Test}">
        <TextBlock>Test should be rendered big</TextBlock>
    </ContentControl>
</Grid>
decyclone
Same problem here...
HCL
I copied it straight from my code editor after I saw it working!
decyclone
Did you compile and run it? When I copy the code in the editor, it works. After compiling it fails. I tested it under .net 3.51 and now also .net 4, same problem.
HCL
+1  A: 

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.

HCL
A: 

That's interesting because I have gotten something Like this to work. Is there a difference?

<Style x:Key="SingleWaveItemContainerStyle" TargetType="{x:Type ListBoxItem}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ListBoxItem}">
                    <Grid Background="{StaticResource WindowBackgroundColor}">
                        <Border Width="125" x:Name="BorderItem" Height="60" Margin="5" BorderThickness="2" ClipToBounds="True" BorderBrush="{StaticResource ViperPanelBorderColor}" Style="{StaticResource ButtonBorderStyle}">
                            <Rectangle x:Name="BackgroundRec" Fill="{StaticResource ViperPanelBorderColor}" Stroke="Transparent" Width="125" Height="60" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                        </Border>
                        <ContentPresenter Name="TheContentPresenter" Width="115" Height="60" Margin="5" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                    </Grid>

                    <ControlTemplate.Triggers>
                        <Trigger Property="IsSelected" Value="true">
                            <Setter TargetName="BorderItem" Property="BorderBrush" Value="{StaticResource NavBar_HighlightBrush}"/>
                            <Setter TargetName="BackgroundRec" Property="Fill" Value="{StaticResource NavBar_HighlightBrush}"/>
                            <Setter TargetName="TheContentPresenter" Property="TextElement.Foreground" Value="White"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>



    <DataTemplate x:Key="SingleWaveDataTemplate" DataType="ListBoxItem">
        <StackPanel>
            <StackPanel Orientation="Horizontal">

                <TextBlock FontWeight="Bold" Text="{Binding Name, Mode=OneWay}" Width="{Binding ElementName=this, Path=Content.DesiredWidth}"/>
            </StackPanel>
            <StackPanel Orientation="Horizontal">

                <TextBlock FontSize="8" Text="{Binding CreationDate, Mode=OneWay}" Width="{Binding ElementName=this, Path=Content.DesiredWidth}"/>
            </StackPanel>
        </StackPanel>
    </DataTemplate>

In xaml page I have:

<ListBox Background="Transparent" ItemTemplate="{StaticResource SingleWaveDataTemplate}" ItemContainerStyle="{StaticResource SingleWaveItemContainerStyle}" BorderThickness="0" ItemsSource="{Binding AllModes, Mode=OneWay}" Height="{Binding ElementName=this, Path=Parent.Height}" SelectedItem="{Binding CurrentSingleWaveModeViewModel, Mode=TwoWay}">
                    <ListBox.ItemsPanel>
                        <ItemsPanelTemplate>
                            <StackPanel Height="{Binding ElementName=Parent, Path=Height}" Background="{StaticResource WindowBackgroundColor}"/>
                        </ItemsPanelTemplate>
                    </ListBox.ItemsPanel>
                </ListBox>

Perhaps we HAVE to use data templates to get the desired effect?

Mike Bynum
Doh, It's obvious why this is working. The textblock is being placed by the datatemplate. which means any affects on the controltemplate will cause this to work.
Mike Bynum