Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UserControl Animate Button's Background

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?

like image 937
Th1sD0t Avatar asked Jan 22 '16 09:01

Th1sD0t


1 Answers

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();
    }
}
like image 92
Salah Akbari Avatar answered Sep 30 '22 07:09

Salah Akbari