温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

WPF中如何自定义GridLengthAnimation

发布时间:2021-07-27 15:00:03 来源:亿速云 阅读:230 作者:小新 栏目:开发技术

小编给大家分享一下WPF中如何自定义GridLengthAnimation,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

需求

我们想在编辑一个列表中某一个条目时,将编辑的详情内容也放置当前面,比如右侧。

可以通过将一个Grid,分成两个Cloumn,动态调整两个Cloumn的Width,就可以实现这个需求。

我们知道,Clomun的Width是个,而默认的动画没有这样子的。我们就需要自己实现这样一人动画。

设计
我们从Animation的类图上看到

WPF中如何自定义GridLengthAnimation

我们可以从需求

我们想在编辑一个列表中某一个条目时,将编辑的详情内容也放置当前面,比如右侧。

可以通过将一个Grid,分成两个Cloumn,动态调整两个Cloumn的Width,就可以实现这个需求。

我们知道,Clomun的Width是个GridLength,而默认的动画没有这样子的。我们就需要自己实现这样一人动画。

设计

我们从Animation的类图上看到AnimationTimeline继承,重写其GetCurrentValue

public class GridLengthAnimation : AnimationTimeline   {     /// <summary>     /// Returns the type of object to animate     /// </summary>     public override Type TargetPropertyType => typeof(GridLength);       /// <summary>     /// Creates an instance of the animation object     /// </summary>     /// <returns>Returns the instance of the GridLengthAnimation</returns>     protected override System.Windows.Freezable CreateInstanceCore()     {       return new GridLengthAnimation();     }       /// <summary>     /// Dependency property for the From property     /// </summary>     public static readonly DependencyProperty FromProperty = DependencyProperty.Register("From", typeof(GridLength),       typeof(GridLengthAnimation));       /// <summary>     /// CLR Wrapper for the From depenendency property     /// </summary>     public GridLength From     {       get       {         return (GridLength)GetValue(GridLengthAnimation.FromProperty);       }       set       {         SetValue(GridLengthAnimation.FromProperty, value);       }     }       /// <summary>     /// Dependency property for the To property     /// </summary>     public static readonly DependencyProperty ToProperty = DependencyProperty.Register("To", typeof(GridLength),       typeof(GridLengthAnimation));       /// <summary>     /// CLR Wrapper for the To property     /// </summary>     public GridLength To     {       get       {         return (GridLength)GetValue(GridLengthAnimation.ToProperty);       }       set       {         SetValue(GridLengthAnimation.ToProperty, value);       }     }       /// <summary>     /// Animates the grid let set     /// </summary>     /// <param name="defaultOriginValue">The original value to animate</param>     /// <param name="defaultDestinationValue">The final value</param>     /// <param name="animationClock">The animation clock (timer)</param>     /// <returns>Returns the new grid length to set</returns>     public override object GetCurrentValue(object defaultOriginValue,       object defaultDestinationValue, AnimationClock animationClock)     {       double fromVal = ((GridLength)GetValue(GridLengthAnimation.FromProperty)).Value;         double toVal = ((GridLength)GetValue(GridLengthAnimation.ToProperty)).Value;         if (fromVal > toVal)         return new GridLength((1 - animationClock.CurrentProgress.Value) * (fromVal - toVal) + toVal, GridUnitType.Star);       else         return new GridLength(animationClock.CurrentProgress.Value * (toVal - fromVal) + fromVal, GridUnitType.Star);     }

如上所示,我们仿着默认动画实现了From,To,同时将其属性定义为GridLength,当动画执行时,我们重写了GetCurrentValue,使其根据From/To属性相关联。

优化

通过以上代码,我们实现了在GridLength变化时,实现动画。但是,试用后我们发现,动画,有点太线性。这个时候,怎么办?

可以通过引入EasingFunction来实现。我们知道EasingFunction其实就是一个与时间t有关的时间函数f(t).通过时间函数的处理,我们使动画过渡不要那么线性。

 /// <summary>     /// The <see cref="EasingFunction" /> dependency property's name.     /// </summary>     public const string EasingFunctionPropertyName = "EasingFunction";       /// <summary>     /// Gets or sets the value of the <see cref="EasingFunction" />     /// property. This is a dependency property.     /// </summary>     public IEasingFunction EasingFunction     {       get       {         return (IEasingFunction)GetValue(EasingFunctionProperty);       }       set       {         SetValue(EasingFunctionProperty, value);       }     }       /// <summary>     /// Identifies the <see cref="EasingFunction" /> dependency property.     /// </summary>     public static readonly DependencyProperty EasingFunctionProperty = DependencyProperty.Register(       EasingFunctionPropertyName,       typeof(IEasingFunction),       typeof(GridLengthAnimation),       new UIPropertyMetadata(null));

对应的,还要重写GetCurrentValue函数。

public override object GetCurrentValue(object defaultOriginValue,       object defaultDestinationValue, AnimationClock animationClock)     {       double fromVal = ((GridLength)GetValue(FromProperty)).Value;         double toVal = ((GridLength)GetValue(ToProperty)).Value;         //check that from was set from the caller       //if (fromVal == 1)       //  //set the from as the actual value       //  fromVal = ((GridLength)defaultDestinationValue).Value;         double progress = animationClock.CurrentProgress.Value;         IEasingFunction easingFunction = EasingFunction;       if (easingFunction != null)       {         progress = easingFunction.Ease(progress);       }           if (fromVal > toVal)         return new GridLength((1 - progress) * (fromVal - toVal) + toVal, GridUnitType.Star);           return new GridLength(progress * (toVal - fromVal) + fromVal, GridUnitType.Star);     }

使用

 <anim:GridLengthAnimation Storyboard.TargetProperty="Width" From="0" To="*" Duration="0:0:0.5"/>

以上是“WPF中如何自定义GridLengthAnimation”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注亿速云行业资讯频道!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI