首页 > 解决方案 > c# 当你将鼠标移到按钮上时,它会慢慢改变按钮的颜色

问题描述

所以我试图让一个按钮更生动,当我将鼠标悬停在按钮上时,它的背面颜色会慢慢从深灰色变为浅灰色,遗憾的是这MouseHover对我来说效果不佳,因为我不得不使用它与if( while,do并且for根本不工作) 所以我将其更改为MouseMoveAnd 以及这产生了它自己的问题,现在只有当我将鼠标移到它上面时颜色才会变浅,这里是代码:

    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

标签: c#colorsmousemove

解决方案


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

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

我创建了一个带有两个动画按钮的演示程序。为了创建具有动画背景颜色的按钮,我首先设置了开始颜色、结束颜色、我希望颜色在每帧中更改的量、鼠标当前所在的按钮以及每个按钮的过渡进度。我最后添加了这个,以便在鼠标悬停在其他东西上后,我可以让按钮逐渐过渡回来。

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

推荐阅读