为 ContentPresenter 中的所有元素设置样式 [英] Set Style for all elements inside ContentPresenter

查看:32
本文介绍了为 ContentPresenter 中的所有元素设置样式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我覆盖了 wpf 扩展器的模板.标题有 ContentPresenter

I overrided the template of wpf expander. The header has ContentPresenter

<ContentPresenter x:Name="HeaderContent"
                  Grid.Column="1"
                  Margin="0,0,4,0"
                  HorizontalAlignment="Left"
                  VerticalAlignment="Center"
                  RecognizesAccessKey="True"
                  SnapsToDevicePixels="True"
                  >
    <ContentPresenter.Resources>
        <Style BasedOn="{StaticResource Expanderheader-Naming}" 
               TargetType="{x:Type TextBlock}" />
     </ContentPresenter.Resources>
</ContentPresenter>

我尝试为里面的所有 TextBlock 添加样式的地方.如果我将标题设置为属性,则我的样式有效:

Where I tried to add my style for all TextBlocks inside. My style works if I set the header as a property:

<Expander Header="HelloWorld">

但是当我尝试以其他方式设置它时却没有.

But it doesn't when I try to set it in the other manner.

<Expander>
    <Expander.Header>
        <Grid x:Name="MyGrid">
            <TextBlock>Hello Man</TextBlock>
        </Grid>  
    </Expander.Header>
</Expander>

如何为 ContentPresenter 中的任何 TextBlocks 设置此样式?

How to set this style for any TextBlocks inside the ContentPresenter?

推荐答案

您在 wpf 中遇到了典型的样式继承问题.

You ran into typical style inheritance issue in wpf.

控件在初始化时寻找它的样式.控件查找样式的方式是在逻辑树中向上移动并询问逻辑父级是否有适合它们的样式存储在父级资源字典中.

A control looks for its style at the point when it is being initalized. The way the controls look for their style is by moving upwards in logical tree and asking the logical parent if there is appropriate style for them stored in parent's resources dictionary.

为了向您解释您在示例中做错了什么,让我们这样想.

To explain to you what you doing wrong in your example lets think like this.

在第一个示例中,标头正确地只是存储HelloWorld",稍后在初始化控件时HelloWorld"将被注入到 ContentPresenter 中.这种方法为HelloWorld"提供了 ContentPresenter 作为其逻辑父项,因此可以正确应用样式,因为可以找到样式.

In first example the header properly is just storing "HelloWorld" and later when control is being initalized "HelloWorld" will be injected into ContentPresenter. This approach provides "HelloWorld" with ContentPresenter being it logical parent and so the style is applied properly since the style can be found.

在第二个示例中,您创建了一个 Grid,在该 Grid 中您有一个 TextBlock.

In second example you create a Grid and inside that Grid you have a TextBlock.

在控制初始化时,TextBlock 的逻辑父级是 Grid,而且 Grid 的逻辑父级是 Expander 本身.在为 TextBlock 寻找样式时,WPF 将询问 TextBlock 的逻辑父级是否在其资源中为 TextBlock 提供了正确的样式,答案是否定的.Grid.Resources 中的 TextBlock 没有合适的样式,Expander.Resources 中的 TextBlock 没有合适的样式.

At point of control initalization the logical parent of your TextBlock is Grid and futhermore Grid's logical parent is Expander itself. When looking for style for TextBlock the WPF will ask TextBlock's logical parent if it has a proper style in its resources for the TextBlock and the answer will be NO. There is no proper style for the TextBlock inside Grid.Resources and there is no proper style for the TextBlock inside Expander.Resources.

正确的样式应该在 ContentPresenter 中,只是在这种情况下 ContentPresenter 不是逻辑树的一部分.

The proper style would be inside ContentPresenter just in this case the ContentPresenter is not part of logical tree.

这就是你在第二个例子中失去风格的原因.

That is how you lose the style in your second example.

为了解决这个问题,我建议您坚持使用第一个示例或更改样式的存储位置.通常所有的样式都存储在Window.Resources中.

In order to fix this I suggest you to stick to first example or to change where the style is being stored to. Usually all styles shall be stored inside Window.Resources.

编辑 2仔细看看这个例子:

<Window.Resources>
    <Style x:Key="textBlockStyle" TargetType="TextBlock">
        <Setter Property="Background" Value="Blue"/>
    </Style>


    <Style TargetType="Button">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Button">
                    <ContentPresenter>
                        <ContentPresenter.Resources>
                            <Style TargetType="TextBlock" BasedOn="{StaticResource textBlockStyle}"/>
                        </ContentPresenter.Resources>
                    </ContentPresenter>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>
<StackPanel>
    <Button Content="Yay, it worked!" />
    <Button>
        <Grid>
            <TextBox Text="It doesn't work this way!"/>
        </Grid>
    </Button>
    <Button>
        <Grid>
            <Grid.Resources>
                <Style TargetType="TextBlock" BasedOn="{StaticResource textBlockStyle}"></Style>
            </Grid.Resources>
            <TextBlock Text="Yay it works again! Woop Woop"/>
        </Grid>
    </Button>
</StackPanel>

这篇关于为 ContentPresenter 中的所有元素设置样式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆