【问题标题】:UserControl Animate Button's BackgroundUserControl 动画按钮的背景
【发布时间】:2016-04-28 20:37:40
【问题描述】:
如果鼠标在Button 上方,我想为Button 的Background 设置动画。
Button 的 Background 绑定到我在 UserControl 的代码隐藏中创建的自定义依赖项属性
... Background="{Binding BGColor, Elementname="QButton"}"
现在,如果我尝试使用 Button 的背景设置动画
<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>
我得到一个例外:
无法为不可变属性(或类似属性)设置动画。
我该如何解决这个问题?
【问题讨论】:
标签:
c#
wpf
animation
user-controls
dependency-properties
【解决方案1】:
基于Mike Hillberg关于Cannot animate '...' on an immutable object instance的精彩文章:
作为一种解决方法,您可以更新绑定,为
Button。这不会干扰绑定 - 对
窗口的前景仍将传播到 Button– 但
Button 将为本地动画制作自己的副本。
所以你的完整解决方案应该是这样的:
<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();
}
}
【解决方案2】:
更改 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>