views:

109

answers:

1

Imagine the following scenario:

this.SetStyle(ControlStyles.UserPaint, true); //this doesn’t change anything

…

void OpenSomeForm()
{
    SomeForm sf = new SomeForm();
    sf.SomeEvent += new … (SomeEventOcurred);
    sf.ShowDialog();
}

private void SomeEventOcurred(…)
{
    OnePanelInThisForm.Invalidate();
}

private void OnePanelInThisForm_Paint(object sender, PaintEventArgs e)
{
     DoSomeDrawing(e.Graphics);
}

Now, OnePanelInThisForm draws correctly when the form loads. But if SomeEventOcurred is Fired from “SomeForm”, the paint event is not fired. If I close and reopen the form it correctly repaints. If I add a button to the form that executes: OnePanelInThisForm.Invalidate(); the panel is correctly repaint.

What am I missing?

UPDATE: Clarification. (why don’t we do this in the first place…)

I have a FORM_A. This FORM_A has a Panel that overrides the Paint event. It’s a standard WinForm. In the Paint it draws a circle. This works. Turns out that FORM_A has a button that opens FORM_B. But before doing that, it subscribes to a custom event in FORM_B called: SomeEvent. (see the sample above). So FORM_B can tell FORM_A about “SomeEvent”.

Now, FORM_B is also a normal WinForm. And it has a normal Button. In the Click event of that button, it opens FORM_C. FORM_C also has an event called SomeEvent and obviously FORM_B subscribes to that event. Exactly like before. The idea is that FORM_C has a button that will trigger that event, notifying the interested subscribers. In this case, when FORM_C fires the event, FORM_B is subscribed and interested.

When FORM_B receives the Call Back, the only thing it does is… notify the interested parties (in this case, FORM A) that the event was fired.

Now, even while Form C is still the top form, the callstack goes back to FormA, to the method defined as callback from the 1st event.

This code Executes. All it does is really somePanel.Invalidate() (or Refresh(), same results).

A Breakpoint in the PAINT method of that panel, reveals that the code doesn’t get called. No Paint event is raised despite being invalidated. I assume that happens because the form (and therefore the panel) is actually covered by FORMB and FORMC (still open).

And that’s all. If I close form C and then Form B, form A still DOESN’T raise the paint event. I’ve tried invalidating the panel on Form activation, but that doesn’t happen.

If I close the form A and reopen it, the drawing is, of course, correct.

Hope this makes it more clear.

There isn’t really much code as this is pretty simple, FORM A > B > C (fire event) -> B -> A -> Invalidate().

+1  A: 

Try using Refresh() instead of Invalidate(). That seems to work more consistently for me, anyways.

sechastain