2010-06-17 10 views
6

¿Por qué el siguiente código simplificado no establece el tamaño de letra de TextBlock en 50?ContentPresenter dentro de ControlTemplate no puede cambiar la propiedad de dependencia adjunta

<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> 

Si cambio el valor de la propiedad Tamaño de Letra, Visual Studio me muestra el texto en el tamaño que quiero. Después de compilar o ejecutar la aplicación, el tamaño del bloque de texto siempre se restablece a su tamaño predeterminado.

También he probado varias versiones con estilos y recursos incrustados pero termino siempre en la situación de que no puedo establecer la herencia de dp adjuntos desde una ControlTemplate que contiene un ContentPresenter. ¿Esto es por diseño?

+0

Nunca antes tuve una situación como esta, pero podría ser por diseño. Creo que ContentPresenter simplemente se reemplaza con el contenido que le proporcionas. – decyclone

Respuesta

12

he encontrado la razón de este comportamiento - es por diseño:

Si el contenido de ContentControl ya es un WPF-Element, es creados antes de utilizarla en el ContenPresenter. El padre lógico del elemento es por lo tanto ContentControl. Puedo comprobar esto a través de cambiar el ContentControl-markup a lo siguiente:

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

En este ejemplo el tamaño del texto es 50 según se desee. Puedo probar esta argumentación también con wpf-visualizer de visual studio. El padre es ContentControl y, a través de dp-inheritance, FontSize se toma del padre (ContentControl), ¡y el texto se muestra con un tamaño de 50!

Otro comportamiento se puede observar si el ContentControl contiene sólo texto como contenido:

<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> 

En este escenario, el cuadro de texto se creado a través de la ContentPresenter porque el texto no se puede introducir en el visual árbol. El cuadro de texto no tiene ningún elemento primario, pero la propiedad TemplateParent conduce a ContentPresenter como elemento primario de TextBoxes y el sistema DP toma FontSize-value a través de la herencia de propiedades de dependencia adjunta de ContentPresenter. Es por eso que en este escenario, el tamaño de fuente se cambia a 50.

Los diferentes escenarios se describen here.

Lo que no entiendo es por qué VS2010 muestra FontSize 50 antes de compilar.

0

¿Qué tal:

<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> 
+0

Mismo problema aquí ... – HCL

+0

¡Lo copié directamente de mi editor de código después de que lo vi funcionar! – decyclone

+0

¿Compiló y ejecutó? Cuando copio el código en el editor, funciona. Después de compilar, falla. Lo probé en .net 3.51 y ahora también en .net 4, el mismo problema. – HCL

0

Eso es interesante porque he conseguido algo así para que funcione. ¿Hay una diferencia?

<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> 

En la página XAML que tengo:

<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> 

Tal vez tenemos que utilizar las plantillas de datos para obtener el efecto deseado?

+0

Doh, es obvio por qué esto está funcionando. El bloque de texto está siendo colocado por el datatemplate. lo que significa que cualquier efecto en la plantilla de control hará que esto funcione. –

Cuestiones relacionadas