.net - control - ejemplos bunifu
AnimaciĆ³n simple en WinForms (3)
Imagine que desea animar algún objeto en un WinForm. Configura un temporizador para actualizar el estado o modelo y anula el evento de pintura del formulario. Pero a partir de ahí, ¿cuál es la mejor manera de volver a pintar el Formulario para la animación?
- ¿Invalidar el formulario tan pronto como termine de dibujar?
- ¿Configura un segundo temporizador e invalida el formulario en un intervalo regular?
- Tal vez hay un patrón común para esto?
- ¿Hay alguna clase .NET útil para ayudar?
Cada vez que necesito hacer esto, descubro un nuevo método con un nuevo inconveniente. ¿Cuáles son las experiencias y recomendaciones de la comunidad SO?
Lo que estás haciendo es la única solución que he usado en WinForms (un temporizador con redibujados constantes). Hay un conjunto de técnicas que puede usar para hacer que la experiencia del usuario sea más fluida (como el doble almacenamiento en el búfer).
Es posible que desee probar WPF. Hay instalaciones integradas para hacer animaciones en WPF, y son mucho más suaves (y requieren menos código y sin sincronización de su parte) que una solución basada en temporizador.
Tenga en cuenta que no necesita usar WPF en toda su aplicación para esa solución; es posible empaquetar esta funcionalidad en un control WPF e insertar el control en una aplicación WinForms (o una aplicación no administrada, para el caso):
Creé una biblioteca que podría ayudar con esto. Se llama Transiciones y se puede encontrar aquí: http://code.google.com/p/dot-net-transitions/
Utiliza temporizadores que se ejecutan en un hilo de fondo para animar los objetos. La biblioteca es de código abierto, por lo que si le sirve, puede ver el código para ver qué está haciendo.
En algunas situaciones, es más rápido y más conveniente no dibujar usando el evento de pintura, pero obtener el objeto Graphics del control / formulario y pintar "on" eso. Esto puede dar algunos problemas con opacidad / anti aliasing / texto, etc., pero podría valer la pena en términos de no tener que volver a pintar todo el shabang. Algo como:
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++]));
}
Uso esto en algunos controles, y tengo imágenes almacenadas para "borrar" el fondo, cuando el objeto de interés se mueve o necesita ser eliminado.