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?
精彩评论