UserControl 动画按钮的背景

UserControl Animate Button's Background

如果鼠标悬停在 Button 上,我想为 ButtonBackground 设置动画。

ButtonBackground 绑定到我在 UserControl

的代码隐藏中创建的自定义依赖项 属性
... Background="{Binding BGColor, Elementname="QButton"}"

现在,如果我尝试使用

为按钮的背景设置动画
<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>

我收到一条异常消息:

cannot animate an immutable property (or similar).

如何解决这个问题?

基于 Mike Hillberg 关于 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.

所以你的完整解决方案应该是这样的:

<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}}"

它引用了一个 IValueConverter 的绑定,如下所示:

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();
    }
}

更改 DP(BGColor) 本身以更改背景。

<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>