Search code examples
c#wpfxamlwpf-controls

How can I trigger style to ContentPresenters inside


I want to trigger style to ContentPresenter's items. How can I do it?

I have template like this. (almost default button style)

<Style x:Key="ImageButtonStyle2" TargetType="{x:Type Button}">
    <Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
    <Setter Property="Background" Value="{StaticResource Button.Static.Background3}"/>
    <Setter Property="BorderBrush" Value="{StaticResource Button.Static.Border3}"/>
    <Setter Property="Foreground" Value="{StaticResource Button.Static.Foreground3}"/>
    <Setter Property="BorderThickness" Value="1"/>
    <Setter Property="HorizontalContentAlignment" Value="Center"/>
    <Setter Property="VerticalContentAlignment" Value="Center"/>
    <Setter Property="Padding" Value="1"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
                    <ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsDefaulted" Value="true">
                        <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Static.Foreground3}"/>
                    </Trigger>
                    <Trigger Property="IsMouseOver" Value="true">
                        <Setter Property="Background" TargetName="border" Value="{StaticResource Button.MouseOver.Background3}"/>
                        <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.MouseOver.Border3}"/>
                    </Trigger>
                    <Trigger Property="IsPressed" Value="true">
                        <Setter Property="Background" TargetName="border" Value="{StaticResource Button.Pressed.Background3}"/>
                        <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Pressed.Border3}"/>
                    </Trigger>
                    <Trigger Property="IsEnabled" Value="false">
                        <Setter Property="Background" TargetName="border" Value="{StaticResource Button.Disabled.Background3}"/>
                        <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Disabled.Border3}"/>
                        <Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="{StaticResource Button.Disabled.Foreground3}"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

And, I'm using button like this.

<Button x:Name="ImageButton2" Style="{DynamicResource ImageButtonStyle2}">
    <StackPanel Orientation="Vertical">
        <Viewbox Width="48.000" Height="30.000">
            <Canvas Width="48.000" Height="30.000">
                <Path Fill="..." Data="..." />
            </Canvas>
        </Viewbox>
        <TextBlock Text="XXX"/>
    </StackPanel>
</Button>

When disabling button, I want to change the Fill, Foreground and Background color of Path and TextBlock items.

I was thinking to write a Setter tag to the Trigger "IsEnable" tag... but I'm stuck with that.

Is there any good way to do that?


Solution

  • If you want the same Background color of Button to reflect in your Path and TextBlock, You can Bind Background property of Button to Path's Fill and TextBlock's Foreground property.

    <Button x:Name="ImageButton2" Height="30" Width="100">
        <StackPanel Orientation="Vertical">
            <Viewbox Width="48.000" Height="30.000">
                <Canvas Width="48.000" Height="30.000">
                    <Path Fill="{Binding Path=Background, RelativeSource={RelativeSource AncestorType=Button}}"
                          Data="..." />
                </Canvas>
            </Viewbox>
            <TextBlock Foreground="{Binding Path=Background, RelativeSource={RelativeSource AncestorType=Button}}"
                       Text="XXX"/>
        </StackPanel>
    </Button>
    

    Or

    If you are looking for different Backgroud, you can try setting Foreground using separate Triggers. Like,

    <TextBlock Text="XXX">
        <TextBlock.Style>
            <Style TargetType="TextBlock">
                <Setter Property="Foreground" Value="Green"/>
                <Style.Triggers>
                    <DataTrigger Binding="{Binding IsEnabled, RelativeSource={RelativeSource AncestorType=Button}}" 
                                 Value="False">
                        <Setter Property="Foreground" Value="Red"/>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </TextBlock.Style>
    </TextBlock>