我设法在我的日程安排中找到了一些空闲时间,以快速启动一个新项目。我敢肯定我的时间本可以花在其他地方更好,但希望我的鞋子里的其他人可能会发现这个有用...
答案是:控件上的图片。将位图渲染到画布上时,几乎不会触发任何事件(如果有的话)。至于控件,它充满了事件——一些是链式的,一些是循环式的,还有递归的添加,所以一个简单的“LocationChanged”事件甚至不会覆盖引擎盖下实际发生的一半。
对于在运行时应用了很多动态动画的控件,我会做的是开发一个两部分集:控件 [渲染] 模板或活动界面(当控件处于静止状态或在动画播放之前),以及具有基本定义属性的动画结构,例如显示图像[渲染的控件]、矩形边界和任何稍后可能应用的动画算法。
编辑:根据要求,以下是之前和之后的代码示例:
// This is the triggering event of the translating animation
private void object_Click(object sender, EventArgs e)
{
// the starting point is at (75,75)
element.Transform(new Point(500, 250));
}
之前:
public class ControlElement : UserControl
{
private Timer tick;
private Point pT0;
public ControlElement() : base()
{
tick = new Timer();
tick.Interval = 30; // about 30fps
tick.Tick += new EventHandler(tick_Tick);
}
void tick_Tick(object sender, EventArgs e)
{
// get the new point from distance and current location/destination
this.Location = Utils.Transform(this.Location, pT0, 3);
if ((pT0.X - this.Location.X)+(pT0.Y - this.Location.Y) <= 0)
{
this.Location = pT0;
tick.Stop();
//this.Visible = true;
}
}
public void Transform(Point destination)
{
pT0 = destination;
//this.Visible = false;
tick.Start();
}
}
之后:我使用DrawToBitmap 功能创建了一个包含控件外观图片的类。它仍然包含与上面相同的动画方法。我不得不添加Location 和LocationChanged 元素,因为这个类不再是一个控件。如果需要访问实际控件时,我会停止渲染并显示它自身的控件实例。
这是渲染调用:
void element_LocationChanged(object sender, EventArgs e)
{
canvas.Invalidate();
}
void canvas_Paint(object sender, PaintEventArgs e)
{
if (element != null)
{
Bitmap bmp = new Bitmap(element.Display);
Pen p = new Pen(Color.FromArgb(128, 128, 128), 1);
e.Graphics.DrawImage(bmp, element.Location);
e.Graphics.DrawRectangle(p,
element.Location.X, element.Location.Y,
bmp.Width, bmp.Height);
}
}