记录一种实现方式:
第一步:
首先定义一个静态类,提供依赖属性,进而方便在xaml中实现绑定:
public static class AnimationBehavior
{
// 定义附加属性
public static readonly DependencyProperty IsAnimatingProperty =
DependencyProperty.RegisterAttached(
"IsAnimating",
typeof(bool),
typeof(AnimationBehavior),
new PropertyMetadata(false, OnIsAnimatingChanged));
public static bool GetIsAnimating(DependencyObject obj) =>
(bool)obj.GetValue(IsAnimatingProperty);
public static void SetIsAnimating(DependencyObject obj, bool value) =>
obj.SetValue(IsAnimatingProperty, value);
private static void OnIsAnimatingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is FrameworkElement element)
{
// 通过 VisualTreeHelper 查找模板中的 Storyboard
if (element.FindResource("ShadowAnimation") is Storyboard storyboard)
{
if ((bool)e.NewValue)
storyboard.Begin(element, true); // 启动动画
else
storyboard.Stop(element); // 停止动画
}
}
}
}
其中实现了依赖属性IsAnimating。
第二步:
在前端中定义动画:
<Page.Resources>
<!-- 将 Storyboard 定义在全局资源中 -->
<Storyboard x:Key="ShadowAnimation">
<DoubleAnimation
AutoReverse="True"
RepeatBehavior="Forever"
Storyboard.TargetName="ShadowEffect"
Storyboard.TargetProperty="Opacity"
From="0.0"
To="1"
Duration="0:0:3" />
<DoubleAnimation
AutoReverse="True"
RepeatBehavior="Forever"
Storyboard.TargetName="myBorder"
Storyboard.TargetProperty="Opacity"
From="0.3"
To="1"
Duration="0:0:3" />
<!--<ThicknessAnimation
AutoReverse="True"
RepeatBehavior="Forever"
Storyboard.TargetName="myBorder"
Storyboard.TargetProperty="Margin"
From="15"
To="12"
Duration="0:0:1.5" />-->
</Storyboard>
</Page.Resources>
其中每一个DoubleAnimation定义中的TargetName是当前界面的其他对象名称:
<Border
x:Name="myBorder"
Grid.ColumnSpan="1"
Margin="4"
localVM:AnimationBehavior.IsAnimating="{Binding CurrentActionHandle.ExecutionState, Converter={StaticResource SingleFlowExecutionStateToBoolJustRunnimg}}"
Background="{Binding CurrentActionHandle.ExecutionState, Converter={StaticResource SingleFlowExecutionStateToBrushColor}}"
CornerRadius="10">
<Border.Effect>
<DropShadowEffect
x:Name="ShadowEffect"
BlurRadius="10"
Direction="12"
Opacity="80"
ShadowDepth="0"
Color="{Binding CurrentActionHandle.ExecutionState, Converter={StaticResource SingleFlowExecutionStateToColor}}" />
</Border.Effect>
</Border>
比如myBorder 和 ShadowEffect;
第三步:
创建绑定关系:
比如上方代码中:
localVM:AnimationBehavior.IsAnimating="{Binding CurrentActionHandle.ExecutionState, Converter={StaticResource SingleFlowExecutionStateToBoolJustRunnimg}}"
给新手解释一下,其中localVM是自己定义的命名空间:
可我这里使用了转换器,可以理解为就是把执行动画的开关绑定到了我后端ViewModel的属性上。