wpf ControlTemplate 中的 ContentPresenter 无法更改附加的依赖项属性

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3063264/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 21:52:41  来源:igfitidea点击:

ContentPresenter within ControlTemplate cannot change attached dependency property

wpfcontroltemplatecontentpresenter

提问by HCL

Why does the following simplified code not sets the font-size of the TextBlock to 50?

为什么下面的简化代码没有将 TextBlock 的 font-size 设置为 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>

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.

如果我更改 FontSize 属性的值,visual studio 会以我想要的大小显示文本。编译或执行应用程序后,文本块的大小始终重置为其默认大小。

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?

我还测试了具有样式和嵌入资源的各种版本,但我总是遇到无法从包含 ContentPresenter 的 ControlTemplate 中设置继承附加 dp 的情况。这是设计使然吗?

回答by HCL

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 parentof the element istherefore ContentControl. I can check this through changing the ContentControl-markup to the following:

如果 ContentControl 的内容已经是 WPF 元素,则在 ContenPresenter 中使用它之前创建它。因此元素的逻辑元素ContentControl。我可以通过将 ContentControl-markup 更改为以下内容来检查这一点:

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

在此示例中,文本大小为所需的 50。我也可以用visual studio的wpf-visualizer来证明这个论点。父级为ContentControl,通过dp-inheritance,从父级(ContentControl)获取FontSize,以50的大小显示文本!

Another behaviorcan be observed if the ContentControl contains only text as content:

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

In this scenario, the TextBoxis created through the ContentPresenterbecause 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.

在这种情况下,TextBox通过 ContentPresenter 创建的,因为无法在可视化树中输入文本。文本框没有父级,但 TemplateParent 属性导致 ContentPresenter 作为 TextBoxes 父级,DP 系统通过从 ContentPresenter 继承的附加依赖项属性获取 FontSize 值。这就是为什么在这种情况下字体大小更改为 50。

The different scenarios are described here.

此处描述不同的场景。

What I don't understand is, why VS2010 shows the FontSize 50 before compiling.

我不明白的是,为什么 VS2010 在编译之前显示 FontSize 50。

回答by decyclone

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>

回答by Mike Bynum

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:

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

Perhaps we HAVE to use data templates to get the desired effect?

也许我们必须使用数据模板来获得预期的效果?