c#将鼠标移到按钮上时缓慢更改按钮的颜色

时间:2019-05-11 14:53:18

标签: c# colors mousemove

因此,我试图通过使鼠标悬停在按钮上来使其按钮更加生动,其背面颜色从深灰色逐渐变为浅灰色,可惜MouseHover效果不佳对我来说,因为我不得不将其与ifwhiledofor根本无法使用)一起使用,所以我将其更改为MouseMove好了,这本身就产生了问题,现在只有当我将鼠标移到它上面时,颜色才会变浅,这是代码:

    private void BtnPlay_MouseMove(object sender, MouseEventArgs e)
    {
        byte coloDat = btnPlay.FlatAppearance.MouseOverBackColor.B;

        if (btnPlay.FlatAppearance.MouseOverBackColor != Color.FromArgb(68, 68, 68))
        {
            coloDat++;
            btnPlay.FlatAppearance.MouseOverBackColor = Color.FromArgb(coloDat, coloDat, coloDat);
            System.Threading.Thread.Sleep(1);
        }
    }

我将在项目中多次使用该代码,那么有没有办法做到这一点而又不浪费文字?

编辑:为避免混淆;我试图使用Button.FlatAppearance.MouseOverBackColor而不是Button.BackgroundColour来完成我的项目。

1 个答案:

答案 0 :(得分:0)

如果要在WPF中创建此样式,只需使用情节提要创建样式。在Windows窗体中,您需要使用计时器。

循环对您不起作用的原因是,循环在与UI相同的线程上运行,因此直到循环结束后才更新UI。要为Windows窗体中的效果设置动画,必须让事件函数结束,以便UI可以更新,然后在下一帧再次调用函数。这就是timer元素的作用。

我创建了一个带有两个动画按钮的演示程序。为了创建具有动画背景颜色的按钮,我首先设置开始颜色,结束颜色,我希望在每个帧中改变颜色的数量,鼠标当前位于上方的按钮以及每个按钮的过渡进度。我添加了最后一个,以便在鼠标悬停在其他物体上之后使按钮逐渐过渡回去。

    private Color startColor = Color.AliceBlue;
    private Color endColor = Color.BlueViolet;
    private double step = 0.01;
    private Button lastOver = null;
    private Dictionary<Button, double> transitionProgress = new Dictionary<Button, double>();

然后,我将两个按钮的事件处理程序附加到相同的函数(以下函数)上。第一个使用ContainsKey,这样我就可以通过将它们分配给这些事件处理函数来使更多按钮具有动画效果。

    private void demoButton_MouseHover(object sender, EventArgs e)
    {
        if (sender != lastOver)
        {
            lastOver = (Button)sender;
            if (!transitionProgress.ContainsKey(lastOver))
            {
                transitionProgress[lastOver] = 0.0;
            }
        }
    }

    private void demoButton_MouseLeave(object sender, EventArgs e)
    {
        lastOver = null;
    }

然后,我使用以下事件处理程序创建了一个Timer。它会遍历每个按钮,并根据鼠标当前是否在该按钮上方进行转换。如果更改了背景色以提高性能,它也只会更新背景色。

    private void styleUpdate_Tick(object sender, EventArgs e)
    {
        for (int i = 0; i < transitionProgress.Count; i++)
        {
            Button button = transitionProgress.Keys.ElementAt(i);
            bool changing = false;
            if (button == lastOver)
            {
                if (transitionProgress[button] < 1.0)
                {
                    transitionProgress[button] = Math.Min(1.0, transitionProgress[button] + step);
                    changing = true;
                }
            }
            else
            {
                if (transitionProgress[button] > 0.0)
                {
                    transitionProgress[button] = Math.Max(0.0, transitionProgress[button] - step);
                    changing = true;
                }
            }
            if (changing)
            {
                double progress = transitionProgress[button];
                button.BackColor = Color.FromArgb(
                    (int)Math.Floor((endColor.R - startColor.R) * progress + startColor.R),
                    (int)Math.Floor((endColor.G - startColor.G) * progress + startColor.G),
                    (int)Math.Floor((endColor.B - startColor.B) * progress + startColor.B)
                    );
            }
        }
    }

必须启用计时器并将时间间隔设置为16

        this.styleUpdate.Enabled = true;
        this.styleUpdate.Interval = 16;
        this.styleUpdate.Tick += new System.EventHandler(this.styleUpdate_Tick);

这似乎是很多代码,但是要将其添加到另一个按钮中,您只需要多两行代码即可。

        this.yourButtonName.MouseLeave += new System.EventHandler(this.demoButton_MouseLeave);
        this.yourButtonName.MouseHover += new System.EventHandler(this.demoButton_MouseHover);