starx207
starx207

Reputation: 367

Button foreground doesn't change when content is StackPanel

I have a button style defined where the template has a ContentPresenter with a name of "contentPresenter". It then has a trigger set up like this:

<ControlTemplate.Triggers>
    <Trigger Property="UIElement.IsEnabled" Value="False">
        <Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="#FF838383" />
    </Trigger>
</ControlTemplate.Triggers>

This trigger simply changes the foreground color of a button to gray when the button is disabled. However, I have one button in my application which does not have simple text as its content. The button looks like this:

<Button Grid.Column="3" Grid.Row="3" Grid.ColumnSpan="2"
            Margin="120 20 30 10"
            Command="{Binding SomeCommand}">
        <StackPanel Orientation="Horizontal">
            <Image Source="{Binding MyImage}" Margin="0 0 2 0"
                   Visibility="{Binding ShowMyImage, Converter={StaticResource BooleanToVisibilityConverter}}"/>
            <TextBlock Text="{Binding ButtonText}" />
        </StackPanel>
    </Button>

The foreground of this button is always the same whether the button is disabled or not. I'm thinking it's because the text for the button is in a textblock within the stackpanel in the content presenter, but I don't know how to get the foreground color changes to be applied to the inner textblock.

I tried changing the Property in the trigger to use "TextBlock.Foreground" instead of "TextElement.Foreground". I also tried binding the Foreground of the inner textblock to the foreground color of the closest ancestor of type FrameworkElement like this:

<TextBlock Text="{Binding ButtonText}" Foreground="{Binding RelativeSource={RelativeSource AncestorType={x:Type FrameworkElement}}, Path=(FrameworkElement.Foreground)}" />

None of this worked. What do I need to do to get the foreground color to apply to the TextBlock inside the StackPanel?

Upvotes: 1

Views: 1648

Answers (1)

Your trigger should be in the Style, and should be setting Foreground on the Button itself, rather than on the ContentPresenter. Then it'll Just Work, with a custom template or with the default template. No need for any extra bindings.

<Style TargetType="Button" x:Key="MyButtonStyle">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Button">
                <Border Background="Beige" BorderBrush="Black" BorderThickness="1" Padding="6,2">
                    <ContentPresenter 
                        />
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <Trigger Property="IsEnabled" Value="False">
            <Setter Property="Foreground" Value="#FF838383" />
        </Trigger>
    </Style.Triggers>
</Style>

Usage:

<Button
    IsEnabled="False"
    Style="{StaticResource MyButtonStyle}"
    >
    <StackPanel>
        <TextBlock 
        >Blah Blah</TextBlock>
        <Button>X</Button>
    </StackPanel>
</Button>
<Button Style="{StaticResource MyButtonStyle}" IsEnabled="False">Testing</Button>

Screenshot (never mind my ugly template):

enter image description here

Upvotes: 2

Related Questions