WPF Animation For SizeChanged Of UIElement

效果图

学到一个新词:Show me the money

背景

这几天查资料,看到 CodeProject 上面的一篇 Post 《Advanced Custom TreeView Layout in WPF》,感谢作者,将 TreeView 重定义了布局,效果如上图所示,区别在于,没有展开和收拢的动画。正巧当下在浏览一些 Behavior 的内容,突发奇想写了一个 SizeChangedAnimationBehavior,可用来附加到大多数 FrameworkElement 上,实现如上的对 SizeChanged 应用动画的效果。

考虑使用一个通用的 SizeChangedAnimationBehavior 来实现对 FrameworkElement 的功能附加,好处是功能可热插拔,可通用等。

一、代码

private void AssociatedObjectOnSizeChanged(object sender, SizeChangedEventArgs sizeChangedEventArgs)
{
	// NewSize 属性,如果存在 double.NaN,则处于一次动画中,跳过此次 OnSizeChanged 处理
	if (double.NaN.Equals(GetNewSize(AssociatedObject).Width) || double.NaN.Equals(GetNewSize(AssociatedObject).Height)) return;

	Size oldSize = GetOldSize(AssociatedObject);

	// 产生动画,注意,这里需要使用 ActualWidth/ActualHeight,并需要使用 FillBehavior.HoldEnd。这里的 Duration 可以扩展为一个附加属性,提高灵活性
	DoubleAnimation wAnimation = new DoubleAnimation(oldSize.Width, AssociatedObject.ActualWidth, new Duration(TimeSpan.FromMilliseconds(150)), FillBehavior.HoldEnd);
	DoubleAnimation hAnimation = new DoubleAnimation(oldSize.Height, AssociatedObject.ActualHeight, new Duration(TimeSpan.FromMilliseconds(150)), FillBehavior.HoldEnd);

	// 动画结束时,需要解除属性的动画锁定,即调用 AssociatedObject.BeginAnimation(FrameworkElement.WidthProperty, null);
	// 然后设置 NewSize 对应动画属性为 0(非 NaN),保证下次动画顺利执行
	wAnimation.Completed += (o, args) =>
	{
		AssociatedObject.BeginAnimation(FrameworkElement.WidthProperty, null);
		double height = GetNewSize(AssociatedObject).Height;
		SetNewSize(AssociatedObject, new Size(0, height));
	};
	hAnimation.Completed += (o, args) =>
	{
		AssociatedObject.BeginAnimation(FrameworkElement.HeightProperty, null);
		double width = GetNewSize(AssociatedObject).Width;
		SetNewSize(AssociatedObject, new Size(width, 0));
	};

	// 设置 OldSize 为 ActualSize,为下次动画做准备
	SetOldSize(AssociatedObject, new Size(AssociatedObject.ActualWidth, AssociatedObject.ActualHeight));

	// 设置 NewSize 为 NaN,表明当前无 NewSize,处于动画执行中,执行结束后,NewSize 将恢复为 0
	SetNewSize(AssociatedObject, new Size(double.NaN, double.NaN));

	// 执行动画
	AssociatedObject.BeginAnimation(FrameworkElement.WidthProperty, wAnimation);
	AssociatedObject.BeginAnimation(FrameworkElement.HeightProperty, hAnimation);
}

代码比较简单,注意注释说明。

其中,OldSize/NewSize 是两个附加属性。

调用如下:

<TextBox x:Name="TxtAnimated" VerticalAlignment="Top" Width="200" TextWrapping="Wrap" Margin="213,12,0,-27" HorizontalAlignment="Left" Grid.Row="2">
	<i:Interaction.Behaviors>
		<behaviors:SizeChangedAnimationBehavior/>
	</i:Interaction.Behaviors>
</TextBox>

二、其他应用效果

1)如下图,Button 的 Resize 操作,可实现动画效果;

2)如下图,Textbox 等实现 Height 的动画效果。此效果灵感(测试UI)来源于 《WPF TextBox with Animated Overflow》,感谢作者。

三、Behavior

关于 Behavior,这里不细说,大佬们的博客太多。本文主要学习于周银辉大佬的 《从WPF的AttachProperty到Sliverlight3中的Behavior》,感谢作者,很棒的文章。


< 原文链接:https://blog.csdn.net/Liwuqingxin/article/details/81138164 转载请保留原文链接,小猿谢过~ >

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值