c#winform - 使用计时器为下拉菜单设置动画

时间:2011-05-31 00:17:15

标签: c# winforms

我正在尝试在winforms中制作动画下拉菜单。当存在mouse_enter事件时,表单将展开,并在存在mouse_leave事件时收缩回原始大小。我用一个计时器来控制“动画”的速度,以达到预期的效果。

运行前几次,“动画”是根据我想要的,但经过几个循环(鼠标在 - >鼠标外 - >鼠标在 - >鼠标外 - >等),动画开始加速,直到它达到一个只是快速出现/消失的程度。

是否有替代方案可以达到这种效果或保持所需的动画效率?

顺便说一下,这是我的第一个问题,如果我违反任何规则/格式等,请告诉我!

    private void setForm()
    {
        this.Location = new Point(Screen.GetWorkingArea(this).Width - this.Width, Screen.GetWorkingArea(this).Height - this.Height);
    }

    Timer Timer1;
    bool mode = false;

    private void B00nZPictureBox_MouseEnter(object sender, EventArgs e)
    {
        mode = true;

        Timer1 = new Timer();
        Timer1.Interval = 10;
        Timer1.Tick += new EventHandler(Timer1_Tick);
        Timer1.Start();
    }

    private void B00nZ_MouseLeave(object sender, EventArgs e)
    {
        mode = false;

        Timer1 = new Timer();
        Timer1.Interval = 10;
        Timer1.Tick += new EventHandler(Timer1_Tick);
        Timer1.Start();
    }

    void Timer1_Tick(object sender, EventArgs e)
    {
        int temp = Screen.GetWorkingArea(this).Height;

        if (mode)
        {
            if (this.Height < temp)
            {
                this.Size = new Size(this.Width, this.Height + 35);
            }
            else if (this.Height > temp)
            {
                if (this.Height - temp > 10)
                {
                    this.Size = new Size(this.Width, this.Height - 3);
                }
                else if (this.Height - temp > 0)
                {
                    this.Size = new Size(this.Width, this.Height - 1);
                }
            }
            else if (this.Height == temp)
            {
                Timer1.Stop();
                Timer1.Dispose();
            }
        }
        else
        {
            if (this.Height > B00nZPictureBox.Height)
            {
                this.Size = new Size(this.Width, this.Height - 35);
            }
            else if (this.Height - B00nZPictureBox.Height <= B00nZPictureBox.Height)
            {
                this.Size = new Size(this.Width, B00nZPictureBox.Height);
            }

            if (this.Height == B00nZPictureBox.Height)
            {
                Timer1.Stop();
                Timer1.Dispose();
            }
        }

        setForm();
    }

3 个答案:

答案 0 :(得分:0)

每次打开菜单时,都会添加一个EventHandler。当计时器熄灭时,它会多次执行你的处理程序。

添加处理程序一次,或每次菜单关闭时将其删除。

答案 1 :(得分:0)

根据你想做的事情,这就是我要做的。首先,创建两个计时器。调用一个enterTimer和另一个leaveTimer。连接他们的事件处理程序一次(在form_load上的设置代码中)。设置他们的间隔,但不要启动它们。然后,当鼠标进入时,启动enterTimer。当鼠标离开时,启动leaveTimer。

你可以玩,等到enterTimer结束,然后再触发leaveTimer或类似的东西,这取决于你想要的逻辑。当另一个计时器被触发时,您也可以停止当前正在运行的计时器。

它看起来像这样:

    //This would be your FormLoad event or somewhere else where you initialize your form information
    private void form_load()
    {
        enterTimer.Interval = 10;
        enterTimer.Tick += new EventHandler(enterTimer_Tick);
        leaveTimer.Interval = 10;
        leaveTimer.Tick += new EventHandler(leaveTimer_Tick);
    }

    private void setForm()
    {
        this.Location = new Point(Screen.GetWorkingArea(this).Width - this.Width, Screen.GetWorkingArea(this).Height - this.Height);
    }

    Timer enterTimer;
    Timer leaveTimer;

    private void B00nZPictureBox_MouseEnter(object sender, EventArgs e)
    {
        enterTimer.Start();
    }

    private void B00nZ_MouseLeave(object sender, EventArgs e)
    {
        leaveTimer.Start();
    }

    void enterTimer_Tick(object sender, EventArgs e)
    {
        //Put your enter logic here
    }

    void leaveTimer_Tick(object sender, EventArgs e)
    {
        //Put your leave logic here
    }

答案 2 :(得分:0)

我建议您在Form加载时只创建一个Timer,并将事件处理程序挂起一次。此后,您只需启用和禁用计时器,而无需处置或重新创建计时器。

现在如果你在菜单完全展开之前进入和离开,你最终会泄漏一个计时器 - 它已经启动,但是全局变量已经被改为一个全新的计时器,所以你无法停止或处理旧的。