【问题标题】:WPF button style not being applied to child elementWPF按钮样式未应用于子元素
【发布时间】:2017-09-29 13:10:37
【问题描述】:

我有这样的按钮样式

<Style x:Key="NormalButtonStyle" TargetType="{x:Type Button}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Grid x:Name="ContentSite">
                    <Grid x:Name="ContainerGrid">
                        <ContentPresenter x:Name="Presenter" Style="{DynamicResource NormalButtonTextStyle}"/>
...

ContentPresenter 的样式在哪里

<Style x:Key="NormalButtonTextStyle" BasedOn="{StaticResource DefaultFontStyle}">
    <Setter Property="TextElement.Foreground" Value="{DynamicResource NormalTextOnDarkBackgroundBrush}" />
...

然后我像这样定义了我的按钮

<Button Style="{StaticResource NormalButtonStyle}">
    <Button.Content>
        <TextBlock Text="Cancel"/>
...

但 TextBlock 并没有以 NormalButtonTextStyle 样式结束。我在运行时检查了元素,内容呈现器肯定有正确的文本前景,但随后子 TextBlock 最终继承自完全不同的东西并获得ControlTextBrush 的前景。

我是否误解了如何将样式应用于子元素?我应该如何定义按钮以便正确应用样式?

【问题讨论】:

  • 您是否尝试在ControlTemplate.Resources 中包含ContentPresenter 样式?

标签: wpf xaml


【解决方案1】:

将&lt;Setter /&gt; 添加到Button style:

<Style x:Key="NormalButtonStyle" TargetType="{x:Type Button}">
    <Setter Property="TextElement.Foreground" Value="{DynamicResource NormalTextOnDarkBackgroundBrush}" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Grid x:Name="ContentSite">
                    <Grid x:Name="ContainerGrid">
                        <ContentPresenter x:Name="Presenter" />
                    </Grid>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

【讨论】:

  • 为什么同一个 setter 不能在内容展示器中工作呢?我不明白为什么差异很重要。
  • ContentPresenter 的样式不适用于 Button 元素。
【解决方案2】:

请查看this。 “正确的样式应该在 ContentPresenter 中,只是在这种情况下 ContentPresenter 不是逻辑树的一部分。”

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

【讨论】:

  • 澄清一下:正如链接的答案所解释的,上面的 sn-p 在这种情况下不起作用 - 请参阅&lt;TextBox Text="It doesn't work this way!"/&gt;。所以这不是一个解决方案。按照链接查看说明。并且看到解决方法是做 Max 所做的:将文本直接放在按钮中,而不是放在子文本块中。当然,这在一般情况下无济于事,因为人们真的想影响子元素。
【解决方案3】:

其他答案可能是解决此问题的正确方法,但不幸的是,这些样式用于大型应用程序,因此我更喜欢仅影响按钮的解决方案。 Parisa 所链接的问题有所帮助;我需要直接设置按钮的内容,以便文本的父级是 ContentPresenter:

<Button Content="Cancel" Style="{StaticResource NormalButtonStyle}"/>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-04
    • 2010-10-12
    • 2014-12-12
    • 1970-01-01
    • 1970-01-01
    • 2010-11-30
    相关资源
    最近更新 更多