1
votes

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?

1
Try Foreground="{Binding Foreground, RelativeSource={RelativeSource AncestorType=Button}}" on the TextBlock. The closest FrameworkElement parent is the StackPanel, which isn't inheriting the foreground color (not sure why not, I haven't looked into dependency property inheritance).15ee8f99-57ff-4f92-890c-b56153
You can't set FrameworkElement.Foreground on a stackpanel, that's probably why not. If you replace the StackPanel with an ItemsControl, you'll get the Button's Foreground via ordinary DP inheritance. However, the StackPanel in the default ItemsPanel is Vertical not Horizontal, so you'll get the wrong layout.15ee8f99-57ff-4f92-890c-b56153
Changing the Relative Source type to Button did work either.starx207
Oh, I see, I was using the default template. You're setting the foreground color on the contentpresenter, which is wrong. Apply the control template in a style and put the trigger in the style's triggers. Set the Foreground property of the button in the setter. That's the conventional way of doing this and it'll work.15ee8f99-57ff-4f92-890c-b56153

1 Answers

2
votes

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