Как я могу добавить движущиеся эффекты к моим элементам управления в C #? - PullRequest
15 голосов
/ 23 мая 2011

У меня есть панель В моей форме C # и у меня есть кнопка. Когда я нажимаю на кнопку, отображается невидимая панель. Вместо этого я хочу, чтобы Панель двигалась или скользила. Например, когда вы нажимаете на выпадающий список, выпадающий список не просто появляется. Я хочу, чтобы моя Панель выглядела так. Как я могу это сделать?

Ответы [ 4 ]

51 голосов
/ 24 мая 2011

Оконная анимация - это встроенная функция для Windows.Вот класс, который использует его:

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);
}

Пример использования:

    private void button2_Click(object sender, EventArgs e) {
        Util.Animate(button1, Util.Effect.Slide, 150, 180);
    }
14 голосов
/ 24 мая 2011

Если вы используете .NET 4 (если не заменяете Task на Thread), функция, подобная этой, может быть началом:

    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();
    }

Использование:

slideToDestination(sender as Control, panel1, 10, () => MessageBox.Show("Done!"));
slideToDestination(sender as Control, panel1, 0, null);

Asдействие, которое вы бы отправили некоторой логической переменной для установки в true, чтобы вы знали, что анимация закончилась или какой-то код для запуска после нее.Остерегайтесь тупиков при вызове с нулевым действием.Вы можете запустить две анимации на одном и том же элементе управления в двух разных направлениях с одинаковой скоростью, и он останется на прежнем уровне, и, конечно, две анимации одновременно могут заставить элемент управления двигаться бесконечно в каком-то направлении, потому что время никогда не закончится1007 *

3 голосов
/ 19 мая 2016

Проверьте библиотеку, которую я написал в прошлом году:

Библиотека анимаций WinForm [.Net3.5 +]

Простая библиотека для анимации элементов управления /значения в .Net WinForm (.Net 3.5 и выше).Ключевой кадр (путь) на основе и полностью настраиваемый.

https://falahati.github.io/WinFormAnimation/

new Animator2D(
        new Path2D(new Float2D(-100, -100), c_control.Location.ToFloat2D(), 500))
    .Play(c_control, Animator2D.KnownProperties.Location);

Перемещает элемент управления c_control из -100, -100 в место, где он находилсяпервое место за 500 мс.

1 голос
/ 24 мая 2011

Для WinForms вы можете начать с того, что местоположение панели находится за пределами экрана.

Использовать таймер, а в событии Tick медленно сдвигать местоположение панели до тех пор, пока оно не достигнет заданных вами координат.*

Множество способов снять шкуру с кошки, но я бы так и сделал.

...