12

I'd like to animate a Button's Background if the Mouse is over the Button.

The Button's Background is bound to a custom dependency property I've created in the Code Behind of my UserControl

... Background="{Binding BGColor, Elementname="QButton"}"

Now if I try to animate the Button's background by using

<Trigger Property="IsMouseOver" Value="True">
    <Trigger.EnterActions>
        <BeginStoryboard>
            <Storyboard>
                <ColorAnimation To="LightBlue"
                                Duration="0:0:2"
                                Storyboard.TargetProperty="Background.Color"/>
            </Storyboard>
        </BeginStoryboard>
    </Trigger.EnterActions>
</Trigger>

I get an exception that says:

cannot animate an immutable property (or similar).

How do I solve this issue?

Salah Akbari
  • 39,330
  • 10
  • 79
  • 109
Th1sD0t
  • 1,089
  • 3
  • 11
  • 37
  • These [http://blogs.msdn.com/b/mikehillberg/archive/2006/09/26/cannotanimateimmutableobjectinstance.aspx](http://blogs.msdn.com/b/mikehillberg/archive/2006/09/26/cannotanimateimmutableobjectinstance.aspx) may help [http://stackoverflow.com/questions/14383214/wpf-storyboard-in-style-returning-a-cannot-animate-color-on-an-immutable-obj](http://stackoverflow.com/questions/14383214/wpf-storyboard-in-style-returning-a-cannot-animate-color-on-an-immutable-obj) – spaceplane Jan 25 '16 at 08:35

2 Answers2

3

Based on Mike Hillberg's great article about Cannot animate '...' on an immutable object instance:

As a workaround, you can update the binding to make a copy of the brush for the Button. That doesn't interfere with the binding – any change to the window’s foreground will still be propagated to the Button– but the Button will make its own copy for a local animation.

So the complete solution for yours should be like this:

<Window x:Class="WpfApplication2.Window3"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:local="clr-namespace:WpfApplication1"
    ....
    ....

Background="{Binding BGColor, Converter={x:Static local:MyCloneConverter.Instance}}"

Which is referencing an IValueConverter for the binding that looks like this:

class MyCloneConverter : IValueConverter
{
    public static MyCloneConverter Instance = new MyCloneConverter();

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value is Freezable)
        {
            value = (value as Freezable).Clone();
        }
        return value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}
Salah Akbari
  • 39,330
  • 10
  • 79
  • 109
0

Change the DP(BGColor) itself to change the Background.

<Button.Triggers>
    <EventTrigger RoutedEvent="MouseEnter">
        <BeginStoryboard>
            <Storyboard>
                <ColorAnimation To="Red" 
                        Duration="0:0:2" 
                        Storyboard.TargetName="QButton"
                        Storyboard.TargetProperty="(BGColor).(SolidColorBrush.Color)"/>
            </Storyboard>
        </BeginStoryboard>
    </EventTrigger>
</Button.Triggers>
AnjumSKhan
  • 9,647
  • 1
  • 26
  • 38