How can I add moving effects to my controls in C#?

前端 未结 4 1328
遇见更好的自我
遇见更好的自我 2020-11-29 04:01

I have a Panel In my C# form and I have a button. When I click on the Button the invisible Panel Shows. Instead of that I want the Panel to move in or slide in. For example

相关标签:
4条回答
  • 2020-11-29 04:42

    For WinForms, you could start with the Panel location being off screen.

    Employ a Timer, and in the Tick event, shift the Panel's location slowly into view until it is at your predefined coordinates.

    Lots of ways to skin a cat, but this is how I'd do it.

    0 讨论(0)
  • Check out the library I wrote last year:

    WinForm Animation Library [.Net3.5+]

    A simple library for animating controls/values in .Net WinForm (.Net 3.5 and later). Key frame (Path) based and fully customizable.

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

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

    This moves the c_control control from -100, -100 to the location it was in first place in 500 ms.

    0 讨论(0)
  • 2020-11-29 04:57

    Window animation is a built-in feature for Windows. Here's a class that uses it:

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

    Sample usage:

        private void button2_Click(object sender, EventArgs e) {
            Util.Animate(button1, Util.Effect.Slide, 150, 180);
        }
    
    0 讨论(0)
  • 2020-11-29 04:57

    If you are using .NET 4 (if not replace Task with Thread), a function similar to this could be a start:

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

    Usage:

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

    As action you would send some boolean variable to set to true so that you know that the animation has finished or some code to run after it. Beware of deadlocks when calling with a null action. You could run two animations on the same control in two different directions with the same speed, and it will stay where it was forever and of course two animations simultaneusly can make the control go infinitely in some direction because the while will never finish :)

    0 讨论(0)
提交回复
热议问题