usuario - ¿Cómo puedo agregar efectos de movimiento a mis controles en C#?
transiciones c# (4)
Tengo un Panel en mi formulario C # y tengo un botón. Cuando hago clic en el botón se muestra el panel invisible. En lugar de eso, quiero que el Panel se mueva o se deslice hacia adentro. Por ejemplo, cuando hace clic en un cuadro combinado, la lista desplegable no aparece. Quiero que mi Panel aparezca así. Cómo puedo hacer eso ?
La animación de ventana es una característica incorporada para Windows. Aquí hay una clase que lo usa:
using System;
using System.ComponentModel;
using System.Windows.Forms;
using System.Runtime.InteropServices;
public static class Util {
public enum Effect { Roll, Slide, Center, Blend }
public static void Animate(Control ctl, Effect effect, int msec, int angle) {
int flags = effmap[(int)effect];
if (ctl.Visible) { flags |= 0x10000; angle += 180; }
else {
if (ctl.TopLevelControl == ctl) flags |= 0x20000;
else if (effect == Effect.Blend) throw new ArgumentException();
}
flags |= dirmap[(angle % 360) / 45];
bool ok = AnimateWindow(ctl.Handle, msec, flags);
if (!ok) throw new Exception("Animation failed");
ctl.Visible = !ctl.Visible;
}
private static int[] dirmap = { 1, 5, 4, 6, 2, 10, 8, 9 };
private static int[] effmap = { 0, 0x40000, 0x10, 0x80000 };
[DllImport("user32.dll")]
private static extern bool AnimateWindow(IntPtr handle, int msec, int flags);
}
Uso de muestra:
private void button2_Click(object sender, EventArgs e) {
Util.Animate(button1, Util.Effect.Slide, 150, 180);
}
Mira la biblioteca que escribí el año pasado:
Biblioteca de animaciones WinForm [.Net3.5 +]
Una biblioteca simple para animar controles / valores en .Net WinForm (.Net 3.5 y posterior). Key frame (Path) basado y completamente personalizable.
https://falahati.github.io/WinFormAnimation/
new Animator2D(
new Path2D(new Float2D(-100, -100), c_control.Location.ToFloat2D(), 500))
.Play(c_control, Animator2D.KnownProperties.Location);
Esto mueve el control c_control
de -100, -100 a la ubicación en la que estaba en primer lugar en 500 ms.
Para WinForms, puede comenzar con la ubicación del Panel fuera de pantalla.
Emplea un temporizador y, en el evento Tick, cambia la ubicación del panel lentamente a la vista hasta que esté en las coordenadas predefinidas.
Muchas maneras de despellejar a un gato, pero así es como lo haría.
Si está utilizando .NET 4 (si no reemplaza Tarea por subproceso), una función similar a esta podría ser un comienzo:
private void slideToDestination(Control destination, Control control, int delay, Action onFinish)
{
new Task(() =>
{
int directionX = destination.Left > control.Left ? 1 : -1;
int directionY = destination.Bottom > control.Top ? 1 : -1;
while (control.Left != destination.Left || control.Top != destination.Bottom)
{
try
{
if (control.Left != destination.Left)
{
this.Invoke((Action)delegate()
{
control.Left += directionX;
});
}
if (control.Top != destination.Bottom)
{
this.Invoke((Action)delegate()
{
control.Top += directionY;
});
}
Thread.Sleep(delay);
}
catch
{
// form could be disposed
break;
}
}
if (onFinish != null) onFinish();
}).Start();
}
Uso:
slideToDestination(sender as Control, panel1, 10, () => MessageBox.Show("Done!"));
slideToDestination(sender as Control, panel1, 0, null);
Como acción, enviaría una variable booleana para establecerla en verdadero para que sepa que la animación ha finalizado o algún código para ejecutar después. Tenga cuidado con los bloqueos cuando llame con una acción nula. Podrías ejecutar dos animaciones en el mismo control en dos direcciones diferentes con la misma velocidad, y permanecerá donde estuvo para siempre y, por supuesto, dos animaciones simultáneamente pueden hacer que el control vaya infinitamente en alguna dirección porque el tiempo nunca terminará :)