简体   繁体   English

如何向 C# 中的控件添加移动效果?

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

I have a Panel In my C# form and I have a button.我的 C# 表单中有一个面板,我有一个按钮。 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 when you click on a combobox the dropdown list doesnt just pop in. I want my Panel to appear like that.相反,我希望面板移入或滑入。例如,当您单击 combobox 时,下拉列表不会弹出。我希望我的面板看起来像那样。 How can I do that?我怎样才能做到这一点?

Window animation is a built-in feature for Windows. Window animation 是 Windows 的内置功能。 Here's a class that uses it:这是使用它的 class :

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

If you are using .NET 4 (if not replace Task with Thread), a function similar to this could be a start:如果您使用的是 .NET 4(如果不使用线程替换任务),则类似于此的 function 可能是一个开始:

    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.作为操作,您将发送一些 boolean 变量设置为 true,以便您知道 animation 已完成或在其后运行一些代码。 Beware of deadlocks when calling with a null action.使用 null 操作调用时请注意死锁。 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:)你可以在同一个控件上以相同的速度在两个不同的方向上运行两个动画,它会永远保持在原来的位置,当然两个动画同时可以使控件 go 在某个方向上无限地运行,因为 while 永远不会结束:)

Check out the library I wrote last year:看看我去年写的库:

WinForm Animation Library [.Net3.5+] WinForm Animation 库 [.Net3.5+]

A simple library for animating controls/values in.Net WinForm (.Net 3.5 and later).一个简单的库,用于在.Net WinForm(.Net 3.5 及更高版本)中为控件/值设置动画。 Key frame (Path) based and fully customizable.基于关键帧(路径)且完全可定制。

https://falahati.github.io/WinFormAnimation/ 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.这会将c_control控件从 -100、-100 移动到它在 500 毫秒内处于首位的位置。

For WinForms, you could start with the Panel location being off screen.对于 WinForms,您可以从不在屏幕上的面板位置开始。

Employ a Timer, and in the Tick event, shift the Panel's location slowly into view until it is at your predefined coordinates.使用计时器,并在 Tick 事件中,将面板的位置缓慢移动到视图中,直到它位于您的预定义坐标处。

Lots of ways to skin a cat, but this is how I'd do it.给猫剥皮的方法很多,但我就是这样做的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM