【问题标题】:c# changing the colour of a button slowly when you move your mouse over itc# 当你将鼠标移到按钮上时,它会慢慢改变按钮的颜色
【发布时间】:2019-05-11 14:53:18
【问题描述】:

所以我尝试让按钮更具动画效果,当我将鼠标悬停在按钮上时,它的背面颜色会慢慢从深灰色变为浅灰色,遗憾的是 MouseHover 对我来说效果不佳因为我必须将它与if 一起使用(whiledofor 根本不起作用)所以我将其更改为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 来完成我的项目。

【问题讨论】:

  • 有什么方法可以使用 WPF 代替 windows 窗体?
  • 我不这么认为,因为我不知道 WPF 但是如果有办法我可以在 WPF 中制作按钮并将其发送到 WF 而不会那么痛苦,我可以尝试一下。

标签: c# colors mousemove


【解决方案1】:

如果您想在 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);

【讨论】:

  • 这太棒了!然而,它似乎只适用于系统样式按钮。为了将其更改为平面,我尝试将button.BackColor 部分更改为button.FlatAppearance.MouseOverBackColor,但它没有做任何事情,我还试图将button.FlatAppearance.BorderColor 作为不同的颜色值潜入代码中,但到目前为止没有任何效果。我应该把它放在哪里?我也只需要一个,但是对于那些可能对功能有疑问的人,如果我们想要有多个颜色变化值,我们应该怎么做?
  • 我尝试将其中一个按钮的 FlatStyle 属性设置为 Flat,只要 FlatAppearance.MouseOverBackColor 未设置为任何内容,现有代码即可正常工作。我还尝试修改代码以动画化 FlatAppearance.MouseOverBackColor 属性,除了它不再淡出之外,这种方法很有效。
  • 啊,我的错,即使您明确表示“然后我使用以下事件处理程序创建了一个 Timer。”我也和设计师一起创建了我的,因此有两个同名的计时器。我会在平面外观上修整一段时间,如果我能找到任何东西,我会告诉你的。谢谢!
猜你喜欢
  • 2022-01-09
  • 2017-10-04
  • 2016-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-20
  • 2017-08-23
相关资源
最近更新 更多