ContentPresenter в ControlTemplate не может изменить вложенное свойство зависимости - PullRequest
6 голосов
/ 17 июня 2010

Почему следующий упрощенный код не устанавливает размер шрифта TextBlock равным 50?

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

Если я изменю значение свойства FontSize, Visual Studio покажет мне текст в нужном мне размере. После компиляции или запуска приложения размер текстового блока всегда сбрасывается до размера по умолчанию.

Я также тестировал различные версии со стилями и встроенными ресурсами, но я всегда заканчиваю ситуацией, когда я не могу установить наследование вложенных dp из ControlTemplate, который содержит ContentPresenter. Это по замыслу?

Ответы [ 3 ]

13 голосов
/ 18 июня 2010

Я нашел причину такого поведения - это по замыслу:

Если ContentControl уже является WPF-элементом, он создается перед его использованием в ContenPresenter . Логический родительский элемент элемента равен , поэтому ContentControl . Я могу проверить это, изменив разметку ContentControl следующим образом:

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

В этом примере размер текста равен 50 по желанию. Я могу доказать эту аргументацию также с помощью wpf-визуализатора visual studio. Родителем является ContentControl, и через dp-наследование FontSize берется из родительского (ContentControl), а текст отображается с размером 50!

Другое поведение можно наблюдать, если ContentControl содержит только текст в качестве содержимого:

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

В этом сценарии TextBox - это , созданный с помощью ContentPresenter , поскольку текст не может быть введен в визуальное дерево. У текстового поля нет родителя, но свойство TemplateParent приводит к ContentPresenter в качестве родителя TextBoxes, а DP-система принимает значение FontSize через наследование свойства присоединенной зависимости от ContentPresenter. Вот почему в этом сценарии размер шрифта изменяется на 50.

Различные сценарии описаны здесь .

Что я не понимаю, так это то, почему VS2010 показывает FontSize 50 перед компиляцией.

0 голосов
/ 13 августа 2010

Это интересно, потому что я получил что-то вроде этого, чтобы работать.Есть ли разница?

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

На странице xaml у меня есть:

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

Возможно, мы ДОЛЖНЫ использовать шаблоны данных для получения желаемого эффекта?

0 голосов
/ 17 июня 2010

Как насчет:

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