【发布时间】:2019-07-12 15:36:49
【问题描述】:
我在代码中创建了一个可重用的 Opacity 动画,它公开了两个依赖属性,因此无需为所有元素定义动画即可运行动画。
如果有人想知道,那么是的,我还在 UWP XAML 中借助行为创建了这些动画,但我得到了相同的结果。问题是在 XAML 中我实际上看不到元素的 Opacity 值的最终结果,但通过代码隐藏我可以插入断点并查看值。
我使用的类是:
public static class VisibilityAnimationHelper
{
private static Storyboard visibleSB = null;
private static Storyboard collapseSB = null;
private static DoubleAnimation collapsedAnim = null;
private static DoubleAnimation visibleAnim = null;
public static readonly DependencyProperty AnimationProperty = DependencyProperty.RegisterAttached("AnimationProperty", typeof(Visibility), typeof(VisibilityAnimationHelper), new PropertyMetadata(Visibility.Visible, AnimationChangedCallback));
public static readonly DependencyProperty ParentProperty = DependencyProperty.RegisterAttached("Parent", typeof(FrameworkElement), typeof(VisibilityAnimationHelper), null);
private static void AnimationChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (!(d is UIElement element)) return;
collapsedAnim = new DoubleAnimation()
{
To = 0.01,
FillBehavior = FillBehavior.Stop
};
collapsedAnim.Completed += delegate
{
element.Visibility = Visibility.Collapsed;
};
visibleAnim = new DoubleAnimation()
{
To = 1.01,
FillBehavior = FillBehavior.Stop
};
visibleAnim.Completed += delegate
{
};
visibleSB = new Storyboard()
{
AutoReverse = false,
Duration = new Duration(TimeSpan.FromSeconds(0.2))
};
Storyboard.SetTarget(visibleAnim, element);
Storyboard.SetTargetProperty(visibleAnim, "Opacity");
collapseSB = new Storyboard()
{
AutoReverse = false,
Duration = new Duration(TimeSpan.FromSeconds(0.2))
};
Storyboard.SetTarget(collapsedAnim, element);
Storyboard.SetTargetProperty(collapsedAnim, "Opacity");
if ((Visibility)e.NewValue == Visibility.Collapsed)
{
if (!collapseSB.Children.Contains(collapsedAnim))
collapseSB.Children.Add(collapsedAnim);
collapseSB.Begin();
}
else
{
element.Visibility = Visibility.Visible;
if (!visibleSB.Children.Contains(visibleAnim))
visibleSB.Children.Add(visibleAnim);
visibleSB.Begin();
}
}
public static void SetParent(DependencyObject element, FrameworkElement value)
{
element.SetValue(ParentProperty, value);
}
public static FrameworkElement GetParent(DependencyObject element)
{
return (FrameworkElement)element.GetValue(ParentProperty);
}
public static void SetAnimationProperty(DependencyObject element, Visibility value)
{
element.SetValue(AnimationProperty, value);
}
public static Visibility GetAnimationProperty(DependencyObject element)
{
return (Visibility)element.GetValue(AnimationProperty);
}
}
您可以使用这个类来测试它是如何工作的。对我来说,最终结果如下所示:
如果你看上面的图片,在第一行,最右边的项目显示 2 颗不透明度设置为 1 的心(作为正常的东西),中间的项目显示一颗心正常,另一颗心有点晕。昏倒的那个刚刚被激活,一次隐藏然后再次显示。如果我继续让心动起来,它们就会一点一点地消失。
当动画完成并且不透明度的结果错误时,我还插入了两个断点。我不确定为什么动画没有设置正确的值。这可能是 SDK 中的错误。
在上面的 2 张图片中,您可以看到元素不透明度的最终结果。当折叠动画完成时,不透明度设置为大约 0.8(当它应该是 0),然后在可见动画完成后,不透明度大约是 0.84(当它应该是 1)。在 UI 中它动画正确,但元素的实际不透明度以某种方式错误地出现。
也许我错误地运行了动画?请在这里提供一些建议。谢谢
【问题讨论】: