Tuesday, August 01, 2006

WindowsFormsParkingWindow a.k.a The devil (reprint)

I had problems with WindowsFormsParkingWindow and a lot of the references on the web pointed to this blog article. Unfortunately, the page was not available when I started searching for it. The only place I could find it was google cache, god bless their big googly hearts :) Therefore I am reprinting the content here, maybe it helps people:

=== WindowsFormsParkingWindow a.k.a The devil ===

I have been working on an application for a few weeks and suddenly it started freezing up for no reason. After copious amounts of swearing and breaking keyboards I found a hidden window in the windows task list. It was called - WindowsFormsParkingWindow. My new worst nightmare.

Nothing seemed to stop this issue from killing my program. After more swearing and cursing I found that this error happened after ALT-Tabbing away from my app and back into it. The parking window would appear and my app would die. I ran WinSpy++ and made the hidden window visible. Behold the glory of the following...

The hidden window contained a user control that I had previously removed off the form. This might not make sense to you now but let me explain the significance. When you remove a control from a form/panel, it gets put onto a WindowsFormsParkingWindow until you put it back onto the panel/form. So the WindowsFormsParkingWindow is kind of like an intermediate place windows keeps user controls before they are put into containers.

You might ask now - "What has that got to do with my app freezing?" Well, I'll tell you exactly why... Because when you remove a control from a panel/form and it has focus, the focus stays on the control (which is now on an invisible form). That's why events fail to fire and the app becomes unresponsive.

The solution? Easy...

Instead of using pnlParent.Clear() or just removing the control you need to do the following:

1. Remove the focus from the current user control by setting it to the parent form.
2. Remove the desired user control by using the ParentControl.RemoveAt( indexOfUsercontrol )

This should clear up the issue.