2010-06-17 8 views
6

Dlaczego poniższy uproszczony kod nie ustawia rozmiaru czcionki obiektu TextBlock na 50?ContentPresenter w aplikacji ControlTemplate nie może zmienić dołączonej właściwości zależności:

Jeśli zmienię wartość właściwości FontSize, wizualne studio pokazuje mi tekst w rozmiarze, który chcę. Po kompilacji lub uruchomieniu aplikacji rozmiar bloku tekstu zawsze jest resetowany do domyślnego rozmiaru.

Przetestowałem także różne wersje ze stylami i osadzonymi zasobami, ale kończę zawsze w sytuacji, w której nie mogę ustawić dziedziczenia dołączonych dpów z obiektu ControlTemplate zawierającego ContentPresenter. Czy to według projektu?

+0

Nigdy wcześniej nie miała takiej sytuacji, ale mogła być zaprojektowana. Sądzę, że ContentPresenter po prostu zamienia się na treści, które do niego dodajesz. – decyclone

Odpowiedz

12

znalazłem przyczynę tego zachowania - jest to zgodne z projektem:

Jeżeli zawartość ContentControl jest już WPF Element jest utworzony przed użyciem go w ContenPresenter. Logiczny dominująca elementu jest zatem ContentControl. Mogę to sprawdzić poprzez zmianę ContentControl-znaczników do:

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

w tym przypadku wielkość tekstu jest 50 to pożądane. Mogę udowodnić tę argumentację również za pomocą wpf-wizualizatora visual studio. Element nadrzędny to ContentControl, a poprzez dziedziczenie dp, rozmiar czcionki jest pobierany z elementu nadrzędnego (ContentControl), a tekst jest wyświetlany w rozmiarze 50!

Innym zachowanie można zaobserwować jeśli ContentControl zawiera tylko tekst jako treści:

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

W tym scenariuszu TextBox jest stworzony przez ContentPresenter ponieważ tekst nie może być wprowadzona w wizualnym drzewo. Pole tekstowe nie ma elementu nadrzędnego, ale właściwość TemplateParent prowadzi do obiektu ContentPresenter jako obiekt macierzysty TextBoxes, a system DP pobiera wartość FontSize przez dołączone dziedziczenie właściwości zależności od obiektu ContentPresenter. Dlatego w tym scenariuszu rozmiar czcionki został zmieniony na 50.

Różne scenariusze opisano na here.

Czego nie rozumiem, to dlaczego VS2010 pokazuje FontSize 50 przed kompilacją.

0

Jak o:

<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

Ten sam problem tutaj ... – HCL

+0

Skopiowałem to bezpośrednio z edytora kodu po tym, jak zobaczyłem, że działa! – decyclone

+0

Czy skompilowałeś i uruchomiłeś? Kiedy kopiuję kod w edytorze, działa. Po kompilacji nie działa. Testowałem to pod .net 3.51, a teraz także .net 4, ten sam problem. – HCL

0

To interesujące, ponieważ uzyskałem coś podobnego do działania. Czy istnieje różnica?

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

Na stronie xaml mam:

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

Być może mamy do wykorzystania szablonów danych, aby uzyskać pożądany efekt?

+0

Doh, To oczywiste, dlaczego to działa. Blok tekstu jest umieszczany przez datatemplate. co oznacza, że ​​wszelkie wpływy na szablonie kontrolnym spowodują, że to zadziała. –

Powiązane problemy