c#中的滑动元素UWP

问题描述:

我对UWP中的动画有疑问。我想在我的应用程序的底部有一个菜单,当点击顶部时,可以滑动(显示)或向下(几乎完全隐藏)。我在之前和之后学习WPF,我知道我可以使用ThicknessAnimation来移动我的控件的边距并使其滑动。不幸的是,在UWP中我不能使用ThicknessAnimations,所以我试图找到另一种方法。我希望这可以用于任意的FrameworkElement(以便能够重用它)。最后,我想出了这个解决方案:c#中的滑动元素UWP

/// <summary> 
    /// Adds a vertical slide animation 
    /// </summary> 
    /// <param name="storyboard">The storyboard to add the animation to</param> 
    /// <param name="seconds">The time the animation will take</param> 
    /// <param name="offset">The distance the element will cover (nagative is up, positive is down)</param> 
    public static void AddVerticalSlide(this Storyboard storyboard, FrameworkElement element, float seconds, double offset) 
    { 

     var slideAnimation = new ObjectAnimationUsingKeyFrames();  

     for (int i = 0; i <= 100; ++i) 
     { 
      double scalar = (double)i/100; 
      slideAnimation.KeyFrames.Add(new DiscreteObjectKeyFrame 
      {     
       Value = new Thickness(0, scalar*offset, 0, -scalar*offset), 
       KeyTime = TimeSpan.FromSeconds(scalar*seconds), 
      }); 
     } 

     //slideAnimation.Duration = TimeSpan.FromSeconds(seconds); 

     // Set the target and target property 
     Storyboard.SetTarget(slideAnimation, element); 
     Storyboard.SetTargetProperty(slideAnimation, "(FrameworkElement.Margin)"); 

     // Add the animation to the storyboard 
     storyboard.Children.Add(slideAnimation); 
    } 

它的工作原理,看起来不错,但这里我要问这个问题的原因是:我不知道,如果它是正确的。我的观点是有更好的方式来滑动物体,而不是手动定义100个点,并使用这个动画将物体移动到每个点。

这个工程,但只是不是偏移元素的理想方式。为什么?因为当你真的只需要一个DoubleAnimation时,你创建了两个很多的DiscreteObjectKeyFrame

你几乎不应该动画元素的Margin。为了改变它的位置,更好的方法是使其变换(TranslateX/TranslateY)的变换值(RenderTransform)变为动画。

动画变换中的任何内容都是有效的。他们脱离了UI线程。传统上,他们在一个特殊的线程中运行叫做排字线程(我认为),但由于创作者更新以往,他们已经根据Windows UI team变得更高性能 -

当您使用故事板和在XAML中转换动画,你在 下使用了Composition。动画以每秒 秒的60帧运行!

下面是使用这样的技术

public static void Slide(this UIElement target, Orientation orientation, double? from, double to, int duration = 400, int startTime = 0, EasingFunctionBase easing = null) 
{ 
    if (easing == null) 
    { 
     easing = new ExponentialEase(); 
    } 

    var transform = target.RenderTransform as CompositeTransform; 
    if (transform == null) 
    { 
     transform = new CompositeTransform(); 
     target.RenderTransform = transform; 
    } 
    target.RenderTransformOrigin = new Point(0.5, 0.5); 

    var db = new DoubleAnimation 
    { 
     To = to, 
     From = from, 
     EasingFunction = easing, 
     Duration = TimeSpan.FromMilliseconds(duration) 
    }; 
    Storyboard.SetTarget(db, target); 
    var axis = orientation == Orientation.Horizontal ? "X" : "Y"; 
    Storyboard.SetTargetProperty(db, $"(UIElement.RenderTransform).(CompositeTransform.Translate{axis})"); 

    var sb = new Storyboard 
    { 
     BeginTime = TimeSpan.FromMilliseconds(startTime) 
    }; 

    sb.Children.Add(db); 
    sb.Begin(); 
} 

注为高性能的这个方法得到的一个例子,有在UWP更强大的动画支持,感谢新组成的API。但是Composition中的偏移动画可能有点tricky

然而,UWP社区的无线工具包做了伟大的工作,包装了一些有用的动画像BlurOffset等随时检查them出来。