开发者

ContentPresenter within ControlTemplate cannot change attached dependency property

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

&l开发者_运维百科t;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?


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.


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>


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?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜