WPF按钮样式未应用于子元素

4

我有一个像这样的按钮样式

<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的前景色。

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


你尝试过将ContentPresenter样式包含在ControlTemplate.Resources中吗? - XAMlMAX
3个回答

4

<Setter /> 添加到 Buttonstyle 中:

<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在内容呈现器中不起作用呢?我不明白为什么这种差异很重要。 - Max
1
ContentPresenter的样式不适用于Button元素。 - mm8

1
请看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>


澄清一下:正如链接的答案所解释的那样,上面的代码片段在这种情况下不起作用 - 请参见<TextBox Text="It doesn't work this way!"/>。因此,这不是一个解决方案。请点击链接查看解释。而且,要看到解决方法是像Max一样直接将文本放在按钮中,而不是在子文本块中。当然,在一般情况下,这并没有帮助,因为我们真正想要影响子元素。 - ToolmakerSteve

0
其他答案可能是解决这个问题的正确方法,但不幸的是,这些样式在一个庞大的应用程序中使用,因此我更喜欢只影响按钮的解决方案。Parisa提供的链接有所帮助;我需要直接设置按钮的内容,以便文本的父级是ContentPresenter:
<Button Content="Cancel" Style="{StaticResource NormalButtonStyle}"/>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接