Search code examples
wpfxamlgradientlineargradientbrush

WPF - Change background from linear to solid on mouseover


I am testing a button that is initially defined with a two color linear gradient brush that appears horizontally. When the user hovers over the button, I would like to change the gradient to a two color appearing vertically and then revert back to default on mouseout. My first efforts have failed, so now I am attempting to replace the brush with a solid color brush to appear, however no animation is occurring.

  • Is it even possible to change gradient directions? If so, an example of how?
  • Regarding the solid color brush (in the code below)...why might this not be animating upon mouseover?
    <Color x:Key="CorpBlue" A="100" R="91" G="99" B="115"/>
    <Color x:Key="CorpGreen" A="100" R="152" G="151" B="70"/>
    <SolidColorBrush x:Key="BrushColor_3" Color="#FF7F00"/>

    <Style TargetType="Button" x:Key="testButton">
    <Setter Property="BorderBrush" Value="{StaticResource BrushColor_3}"/>
    <Setter Property="BorderThickness" Value="2"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Button">
                <Border x:Name="testBed"
                            Margin="{TemplateBinding Margin}" 
                            BorderBrush="{TemplateBinding BorderBrush}" 
                            BorderThickness="{TemplateBinding BorderThickness}"
                            CornerRadius="10">
                        <Border.Background>
                            <LinearGradientBrush StartPoint="0,0" EndPoint="0,1" x:Name="basicBrush" >
                                <LinearGradientBrush.GradientStops>
                                    <GradientStop x:Name="BackgroundGradientStop1" Offset="0" Color="{StaticResource CorpGreen}"/>
                                    <GradientStop x:Name="BackgroundGradientStop2" Offset="0.5" Color="{StaticResource CorpBlue}"/>
                                    <GradientStop x:Name="BackgroundGradientStop3" Offset="1" Color="{StaticResource CorpGreen}"/>
                                </LinearGradientBrush.GradientStops>
                            </LinearGradientBrush>
                        </Border.Background>
                        <ContentPresenter Margin="{TemplateBinding Padding}"
                                          Content="{TemplateBinding Content}"
                                          ContentTemplate="{TemplateBinding ContentTemplate}"
                                          HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                          VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                    </Border>
                    <ControlTemplate.Triggers>
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="IsEnabled" Value="True"/>
                                <Condition Property="IsPressed" Value="True"/>
                            </MultiTrigger.Conditions>
                            <MultiTrigger.EnterActions>
                                <BeginStoryboard>
                                    <Storyboard x:Name="MouseDownAnimation">
                                        <ColorAnimation Storyboard.TargetName="BackgroundGradientStop1"
                                                        Storyboard.TargetProperty="Color"
                                                        To="{StaticResource CorpBlue_T1}"
                                                        Duration="0:0:0:1"/>
                                        <ColorAnimation Storyboard.TargetName="BackgroundGradientStop2"
                                                        Storyboard.TargetProperty="Color"
                                                        To="{StaticResource CorpGreen_T1}"
                                                        Duration="0:0:0:1"/>
                                    </Storyboard>
                                </BeginStoryboard>
                            </MultiTrigger.EnterActions>
                            <MultiTrigger.ExitActions>
                                <BeginStoryboard>
                                    <Storyboard x:Name="MouseUpAnimation">
                                        <ColorAnimation Storyboard.TargetName="BackgroundGradientStop1"
                                                        Storyboard.TargetProperty="Color"
                                                        To="{StaticResource CorpBlue}"
                                                        Duration="0:0:0:1"/>
                                        <ColorAnimation Storyboard.TargetName="BackgroundGradientStop2"
                                                        Storyboard.TargetProperty="Color"
                                                        To="{StaticResource CorpGreen}"
                                                        Duration="0:0:0:1"/>
                                    </Storyboard>
                                </BeginStoryboard>
                            </MultiTrigger.ExitActions>
                        </MultiTrigger>
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="IsEnabled" Value="True"/>
                                <Condition Property="IsMouseOver" Value="True"/>
                            </MultiTrigger.Conditions>
                            <MultiTrigger.EnterActions>
                                <BeginStoryboard>
                                    <Storyboard x:Name="MouseOverAnimation"  >
                                        <ColorAnimation Storyboard.TargetName="testBed"
                                                        Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)"
                                                        From="Black" To="Green"
                                                        Duration="0:0:0:1"/>
                                    </Storyboard>
                                </BeginStoryboard>
                            </MultiTrigger.EnterActions>
                        </MultiTrigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

Solution

  • The color resources you defined are so similar that I was unable to visually detect any change at all. After I changed the Alpha (A) channel from 100 to 255 (fully opaque) and changed the colors to something with some contrast, the gradient color animation you have could be seen to work fine.

    The following illustrates how to animate the gradient direction from horizontal to vertical.

    The LinearGradientBrush can't be a target, but its properties can be bound. LinearGradientBrush.EndPoint is a point. So I put a Point in a dependency property somewhere, bind to that, and animate the point with PointAnimation.

    You'll have to animate it back in the exit actions as well.

    <ControlTemplate TargetType="Button">
        <Border x:Name="testBed"
                Margin="{TemplateBinding Margin}" 
                BorderBrush="{TemplateBinding BorderBrush}" 
                BorderThickness="{TemplateBinding BorderThickness}"
                CornerRadius="10"
                >
            <Border.Tag>
                <!-- You could find a better place to put this, but it'll do for an example. -->
                <!-- See binding on basicBrush.EndPoint just below -->
                <Point X="0" Y="1" />
            </Border.Tag>
            <Border.Background>
                <LinearGradientBrush StartPoint="0,0" EndPoint="{Binding Tag, ElementName=testBed}" x:Name="basicBrush">
                    <LinearGradientBrush.GradientStops>
                        <GradientStop x:Name="BackgroundGradientStop1" Offset="0" Color="{StaticResource CorpGreen}"/>
    

    Down in the triggers:

    <Storyboard x:Name="MouseDownAnimation">
        <ColorAnimation Storyboard.TargetName="BackgroundGradientStop1"
                        Storyboard.TargetProperty="Color"
                        To="{StaticResource CorpBlue_T1}"
                        Duration="0:0:0:1"/>
        <ColorAnimation Storyboard.TargetName="BackgroundGradientStop2"
                        Storyboard.TargetProperty="Color"
                        To="{StaticResource CorpGreen_T1}"
                        Duration="0:0:0:1"/>
    
        <PointAnimation Storyboard.TargetName="testBed"
                        Storyboard.TargetProperty="Tag"
                        From="0,1"
                        To="1,0"
                        Duration="0:0:0:1"
                        />