我正在尝试使用问题How to smoothly animate Windows Forms location with different speeds?
上给出的代码顺利移动表单但由于某种原因,我的this.Invalidate()调用永远不会启动OnPaint事件。表单上是否需要一些配置才能实现此目的?
修改
涉及线程,因为它在具有自己的messageloop的后台工作程序中运行。这是代码:
public class PopupWorker
{
public event PopupRelocateEventHandler RelocateEvent;
private BackgroundWorker worker;
private MyPopup popupForm;
public PopupWorker()
{
worker = new BackgroundWorker();
worker.DoWork += worker_DoWork;
}
void worker_DoWork(object sender, DoWorkEventArgs e)
{
popupForm = PopupCreator.CreatePopup("Title", "BodyText");
this.RelocateEvent += popupForm.OnRelocate;
popupForm.CustomShow();
Application.Run();
}
public void Show()
{
worker.RunWorkerAsync();
}
public void PopupRelocate(object sender, Point newLocation)
{
if (popupForm.InvokeRequired)
popupForm.Invoke(new PopupRelocateEventHandler(PopupRelocate), new object[] {sender, newLocation});
else
RelocateEvent(this, newLocation);
}
}
表格:
public void OnRelocate(object sender, Point newLocation)
{
targetLocation = newLocation;
this.Invalidate();
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
if (Location.Y != targetLocation.Y)
{
Location = new Point(Location.X, Location.Y + 10);
if (Location.Y > targetLocation.Y)
Location = targetLocation;
this.Invalidate();
}
}
答案 0 :(得分:3)
链接问题中的代码使用Application.DoEvents,这是让OnPaint发生的关键部分。
没有它,您可以使用Form.Refresh()而不是Invalidate。
有关详细信息,请参阅this question。
您的代码确实显示了一些问题,但它并不完整。让我们从基础知识开始,为了使表单移动所需要的只是启用一个计时器,并且:
private void timer1_Tick(object sender, EventArgs e)
{
this.Location = new Point(this.Location.X + 2, this.Location.Y + 1);
}