.net WinForms 中的简单动画
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11318/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Simple animation in WinForms
提问by Chris Smith
Imagine you want to animate some object on a WinForm. You setup a timer to update the state or model, and override the paint event of the Form. But from there, what's the best way to continually repaint the Form for the animation?
想象一下,您想为 WinForm 上的某个对象设置动画。您设置一个计时器来更新状态或模型,并覆盖表单的绘制事件。但是从那里开始,不断为动画重新绘制表单的最佳方法是什么?
- Invalidate the Form as soon as you are done drawing?
- Setup a second timer and invalidate the form on a regular interval?
- Perhaps there is a common pattern for this thing?
- Are there any useful .NET classes to help out?
- 完成绘图后立即使表格无效?
- 设置第二个计时器并定期使表单无效?
- 也许这件事有一个共同的模式?
- 是否有任何有用的 .NET 类可以提供帮助?
Each time I need to do this I discover a new method with a new drawback. What are the experiences and recommendations from the SO community?
每次我需要这样做时,我都会发现一种具有新缺点的新方法。SO 社区有哪些经验和建议?
采纳答案by Peteter
In some situations, it's faster and more convenient to not draw using the paint event, but getting the Graphics object from the control/form and painting "on" that. This may give some troubles with opacity/anti aliasing/text etc, but could be worth the trouble in terms of not having to repaint the whole shabang. Something along the lines of:
在某些情况下,不使用paint 事件进行绘制,而是从控件/窗体中获取Graphics 对象并在其上“绘制”会更快、更方便。这可能会给不透明度/抗锯齿/文本等带来一些麻烦,但就不必重新绘制整个 shabang 而言,这可能是值得的。类似的东西:
private void AnimationTimer_Tick(object sender, EventArgs args)
{
// First paint background, like Clear(Control.Background), or by
// painting an image you have previously buffered that was the background.
animationControl.CreateGraphics().DrawImage(0, 0, animationImages[animationTick++]));
}
I use this in some Controls myself, and have buffered images to "clear" the background with, when the object of interest moves or need to be removed.
我自己在一些控件中使用它,并在感兴趣的对象移动或需要移除时缓冲图像以“清除”背景。
回答by Richard Shepherd
I've created a library that might help with this. It's called Transitions, and can be found here: https://github.com/UweKeim/dot-net-transitions. Available on nuget as the dot-net-transitions package
我创建了一个可能对此有所帮助的库。它叫做 Transitions,可以在这里找到:https: //github.com/UweKeim/dot-net-transitions。作为dot-net-transitions 包在 nuget 上可用
It uses timers running on a background thread to animate the objects. The library is open-source, so if it is any use to you, you can look at the code to see what it's doing.
它使用在后台线程上运行的计时器来为对象设置动画。该库是开源的,因此如果它对您有用,您可以查看代码以了解它在做什么。
回答by TheSmurf
What you're doing is the only solution I've ever used in WinForms (a timer with constant redrawings). There are a bunch of techniques that you can use to make the user's experience with it smoother (such as double-buffering).
您正在做的是我在 WinForms 中使用过的唯一解决方案(一个不断重绘的计时器)。有很多技术可以用来让用户体验更流畅(例如双缓冲)。
You might want to give WPF a try. There are built-in facilities for doing animations in WPF, and they're much smoother (and require less code and no synchronization on your part) than a timer-based solution.
您可能想尝试一下 WPF。在 WPF 中有用于制作动画的内置工具,它们比基于计时器的解决方案更流畅(并且需要更少的代码并且不需要同步)。
Note that you do not need to use WPF throughout your whole app for that solution; it's possible to pack this functionality into a WPF control and embed the control in a WinForms application (or an unmanaged app, for that matter):
请注意,对于该解决方案,您不需要在整个应用程序中使用 WPF;可以将此功能打包到 WPF 控件中,并将控件嵌入 WinForms 应用程序(或非托管应用程序,就此而言):

