2010-06-17 4 views
6

Perché il seguente codice semplificato non imposta la dimensione carattere di TextBlock su 50?ContentPresenter in ControlTemplate non può modificare la proprietà di dipendenza collegata

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

Se cambio il valore della proprietà FontSize, Visual Studio mi mostra il testo nella dimensione che voglio. Dopo aver compilato o eseguito l'app, la dimensione del blocco di testo viene sempre ripristinata alla sua dimensione predefinita.

Ho anche provato varie versioni con gli stili e le risorse incorporate ma termino sempre nella situazione in cui non posso impostare l'ereditarietà dei dp allegati da un ControlTemplate che contiene un ContentPresenter. È questo in base alla progettazione?

+0

Mai avuto una situazione come questa prima, ma potrebbe essere di progettazione. Penso che ContentPresenter si sostituisca semplicemente con il contenuto che fornisci. – decyclone

risposta

12

ho trovato la ragione di questo comportamento - è in base alla progettazione:

Se il contenuto di ContentControl è già un WPF-elemento, è creato prima di utilizzarlo in il ContentPresenter. Il logico genitore dell'elemento è pertanto ContentControl. Posso controllare questo attraverso cambiando la ContentControl-markup al seguente:

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

In questo esempio la dimensione del testo è 50 come desiderato. Posso provare questa argomentazione anche con wpf-visualizer di visual studio. Il genitore è ContentControl e tramite dp-inheritance, FontSize è preso dal genitore (ContentControl) e il testo è mostrato con una dimensione di 50!

Un altro comportamento si può osservare se il ContentControl contiene solo testo come contenuto:

<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 questo scenario, il TextBox è creato attraverso il ContentPresenter perché il testo non può essere immesso nel visiva albero. La casella di testo non ha un genitore ma la proprietà TemplateParent conduce a ContentPresenter come padre di TextBoxes e il sistema DP assume il valore FontSize tramite l'ereditarietà di proprietà di dipendenza allegata da ContentPresenter. Ecco perché in questo scenario la dimensione del carattere viene modificata in 50.

I diversi scenari sono descritti here.

Quello che non capisco è, perché VS2010 mostra FontSize 50 prima della compilazione.

0

ne dite:

<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

Lo stesso problema qui ... – HCL

+0

L'ho copiato direttamente dal mio editor di codice dopo averlo visto funzionare! – decyclone

+0

Lo hai compilato ed eseguito? Quando copio il codice nell'editor, funziona. Dopo averlo compilato fallisce. L'ho provato sotto .net 3.51 e ora anche .net 4, stesso problema. – HCL

0

Questo è interessante perché ho ottenuto qualcosa come questo per funzionare. C'è una differenza?

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

Nella pagina XAML che ho:

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

Forse dobbiamo usare modelli di dati per ottenere l'effetto desiderato?

+0

Doh, è ovvio perché questo funziona. Il blocco di testo viene posizionato dal datatemplate. il che significa che qualsiasi effetto sul controltemplate farà sì che funzioni. –