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