在本文中,将探讨一个简单但可扩展的Windows Forms动画框架的概念。Windows Presentation Foundation (WPF) 提供了许多曾经需要花费大量时间在Windows Forms中编码的功能。WPF的一个关键特性是它支持对依赖属性进行动画处理。
本文将展示一个概念,并提供一个简单但可扩展的动画框架,用于Windows Forms。可以查看文章中的Carousel Control for Windows Forms,它建立在这个动画框架之上。
该项目实现了一个通用接口,定义了动画类型,并使用反射在目标属性上调用动画。这使得工作变得简单,就像在WPF中一样,只需几行代码就可以动画化按钮的宽度!通过动画化一些简单的小东西,可以创造出奇迹!
IntAnimation widthAnimation = new IntAnimation
{
AutoReset = true,
AutoReverse = true,
From = 100,
To = 250,
By = 1,
Interval = 10,
Duration = 3000
};
this.button1.Animate<int>("Width", widthAnimation);
这是否足够简单?继续阅读以了解更多!
IAnimation<T> 接口实现了以下字段,这些字段代表了动画属性所需的信息。类型T标记了动画处理的目标属性的类型。例如,要动画化Control的Width,类型将是整数。
以下是接口的字段和属性:
public interface IAnimation<T>
{
bool AutoReset { get; set; }
bool AutoReverse { get; set; }
int Interval { get; set; }
int Duration { get; set; }
T By { get; set; }
T From { get; set; }
T To { get; set; }
T GetNewValue(int delta);
event AnimationEventHandler<T> Completed;
event AnimationEventHandler<T> Started;
event AnimationEventHandler<T> Freezed;
}
Animator类定义了静态扩展方法来调用目标属性上的动画。以下是它的工作原理:
1. 通过其名称获取目标对象的PropertyInfo。
private static PropertyInfo GetPInfo(object target, string property, Type t)
{
if (t == null || target == null || String.IsNullOrEmpty(property))
return null;
return target.GetType().GetProperty(property, t);
}
2. 在目标属性上设置更新后的值。
pinfo.SetValue(target, newValue, null);
实际的工作是在静态扩展方法Animator.Animate()中进行的,它消耗目标对象、属性名称和动画类型的实例,该实例持有关于类型和值的信息。
Animator内部有两个计时器在运行,一个在特定间隔上更新目标属性上的值,另一个更新动画器的状态。
animSteps.Tick += (_, __) =>
{
T newValue = animation.GetNewValue(++delta);
pinfo.SetValue(target, newValue, null);
};
animDuration.Elapsed += (_, __) =>
{
if (!state.IsFreezed)
{
delta = -1;
state.IsReversed = animation.AutoReverse ? !state.IsReversed : false;
}
if (!animSteps.Enabled && !animDuration.Enabled)
state.RaiseCompleted(target);
};
这是一个通用实现,它可以用于动画化任何目标类型的任何公共属性。源代码包括了Int和double类型的实现。
首次发布 - 2011年10月2日 几次编辑修订 - 2011年10月3日 新增高级使用模式示例 - 2011年10月4日