我正在尝试在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();
}
答案 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,并将事件处理程序挂起一次。此后,您只需启用和禁用计时器,而无需处置或重新创建计时器。
现在如果你在菜单完全展开之前进入和离开,你最终会泄漏一个计时器 - 它已经启动,但是全局变量已经被改为一个全新的计时器,所以你无法停止或处理旧的。