Thursday, September 24, 2009

Keeping Track Of Non-Modal Dialog Windows

I had a problem.

My problem revolved around a modal dialog window. One which the user base needed to be non-modal.

Now, initially, that sounds like an easy task. It's just a matter of changing the ShowDialog method to a simple Show.

But that's just initially.

The problem comes because this dialog was editing the elements of a list. So, for each page viewed, I could have 1-to-N dialogs, spread out over 1-to-N pages. And I couldn't re-use the dialog windows over and over again.

Of course, even this is not THAT big of an issue--at least until you realize that there is a situation where I do need to re-use a dialog window. Basically whenever a user clicks on an already displayed line item, I need to bring that dialog to the front as opposed to popping a new one up.

And this had to be done without having a handle on the forms, and the control which is spawning these dialogs (and its parents) are not set up as MDI parents.

So, what the provides is the following list of issues:

  • Need to be able to launch N dialogs
  • Those N Dialogs cannot be re-used across list items
  • If a list item is already loaded in a dialog, that dialog just needs to be granted focus
  • No MDI Interface & no time to implement a traditional MDI interface
So, I turned to my trusty friend GOOGLE, and found pretty much zip. Apparently, most non-modal dialogs are either a singleton type thing or they're spawned and forgotten. Which for the most part, that's the case. I can see that the constraints that I'm working under are not common.

So, after thinking some more, I create a new project in Visual Studio to allow me to play with things. I tried grabbing the HWND object for my dialog but that was obscenely bulky and prone to errors.

Then I had the grand idea of keeping a list of these dialog windows in my control. That way I would have a handle for all of them.

So I tried it. I launched three different list item elements, all of them popped up. When I went back to the main form, and clicked one of those list item elements again, the correct dialog gained focus. I was scrubbing my hands and getting ready to do that "I control the world and am a genius" cackle.

But I had one last test, which is I closed one of the dialog and then clicked its corresponding list item.

And got nothing. Zilch.

After a quick breakpoint add, I discovered that those closed dialogs still existed in my list.

So, I proceed to bang my head on my desk.

Then I went and retreived my boss, and presented the problem to him, hoping he'd have some brilliant idea. Which he failed to grasp the problem until I reminded him that whole "there's no MDI" thing, at which point he got this kind of sick/amazed/amused look and basically told me I should have fun trying to solve this one.

Which is when I remembered events.

Oh those beautiful, wonderful things called events.

What had slipped my mind is that an event is raised to the window and then sent down the control chain until it finds a control that basically says "I'm supposed to handle that!"

So I go into my code, and to the CLOSING event of the dialog I add a new event that I raised. One that is consumed by my calling class.

When I handle said event, I know that I can remove the associated dialog from my list of open dialogs.

And wouldn't you know it, it all works just about perfectly.

No comments:

Blog Widget by LinkWithin