Adam Goss
Adam Goss

Reputation: 1027

WPF Style Triggers TemplateBinding

I'm new to WPF and I am struggling to find the solution to what I'm trying to do as I'm still a little uncertain as to whether I'm doing this correctly.

I have the following style defined for a button

<Style x:Key="ToolBarButtonStyle" TargetType="{x:Type Button}">
    <Setter Property="Margin" Value="5" />
    <Setter Property="BorderBrush" Value="White" />
    <Setter Property="Background" Value="{DynamicResource CompanyBlue}" />
    <Setter Property="Foreground" Value="White" />
    <Setter Property="FontWeight" Value="Bold" />
    <Setter Property="FontSize" Value="20" />
    <Setter Property="Width" Value="100" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Button">               
                <Border x:Name="ButtonBorder" BorderThickness="5" CornerRadius="5"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        Background="{TemplateBinding Background}"
                        Width="{TemplateBinding Width}">
                    <ContentPresenter Margin="10" HorizontalAlignment="Center" VerticalAlignment="Center" />
                </Border>


            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="Button.Background">
                <Setter.Value>
                    <LinearGradientBrush StartPoint="0,-0.2" EndPoint="0,1.2">
                        <LinearGradientBrush.GradientStops>
                            <GradientStop Color="White" Offset="0" />
                            <GradientStop Color="{ORIGINAL-COLOR}" Offset="0.5" />
                            <GradientStop Color="White" Offset="1" />
                        </LinearGradientBrush.GradientStops>
                    </LinearGradientBrush>
                </Setter.Value>
            </Setter>
        </Trigger>
    </Style.Triggers>
</Style>

In the XAML, where I have put the placeholder {ORIGINAL-COLOR}, I essentially want this to be the value that is used previously set with {TemplateBinding Background} for the control template of the style.

I've seen suggestions that I should use {Binding RelativeSource={RelativeSource TemplatedParent}, Path=Background} but this is not working.

Thanks in advance for any help.

Upvotes: 3

Views: 4097

Answers (3)

pbalaga
pbalaga

Reputation: 2068

I believe the problem is that LinearGradientBrush is not a FrameworkElement and doesn't belong to layout tree. Only FrameworkElements have DataContext property and in consequence can make use of bindings. What you're trying to do is to set up a Binding on GradientStop.

Your trigger should look like this:

            <Trigger Property="IsMouseOver" Value="True">
                <Setter Property="Button.Background" 
                        Value="{TemplateBinding Background, Converter={StaticResource myConverter}}">
                </Setter>
            </Trigger>

And myConverter is a custom converter class that will take value of Background and return a complete LinearGradientBrush instance created from input brush. I'll assume you know how to write converters. Remember it needs to be added to resources.

More or less something like this:

    class BrushToGradient : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var brush = (Brush)value;
        var gradient = new LinearGradientBrush();

        //Make it manually
        gradient.GradientStops.Add(...);
        //...
        return gradient;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Upvotes: 2

yo chauhan
yo chauhan

Reputation: 12295

Try it like this

<GradientStop Color="White" Offset="0" />
<GradientStop Color="{DynamicResource CompanyBlue}"  Offset="0.5" />
<GradientStop Color="White" Offset="1" />

I hope this will help.

Upvotes: 0

Rohit Vats
Rohit Vats

Reputation: 81233

You can't bind Color with Background property since return type of Background is Brush and not Color.

Bind with Color property of Brush. Since background is binded to resource CompanyBlue so use that binding in your trigger as well -

<GradientStop Color="{Binding Color, Source={StaticResource CompanyBlue}}"
              Offset="0.5" />

Upvotes: 0

Related Questions