Winforms Invalidate doesn't fire up OnPaint

2.4k Views Asked by At

I'm trying to move a form smoothly using code given on question How to smoothly animate Windows Forms location with different speeds?

But for some reason my this.Invalidate() call will never fire up the OnPaint event. Is there some configuration that's required on the form for this to be possible?

Edit:

Threading is involved, as it runs in a backgroundworker with it's own messageloop. Here's the code :

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

Form :

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

There are 1 best solutions below

4
On

The code in the linked question uses Application.DoEvents, that is the key part for letting OnPaint happen.
Without that, you could use Form.Refresh() instead of Invalidate.

For more details, see this question.

Edit:

Your code does show some problems, but it is not complete. Let's start with the basics, in order to make a Form move all you need is to enable a Timer and this:

private void timer1_Tick(object sender, EventArgs e)
{            
    this.Location = new Point(this.Location.X + 2, this.Location.Y + 1);
}