Winforms Invalidate不会启动OnPaint

时间:2009-12-18 17:40:42

标签: c# winforms onpaint invalidation

我正在尝试使用问题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();
    }
}

1 个答案:

答案 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);
}