Windows Develop Bookmark and Share   
 index > Windows Forms General > Popup Window not Responding
 

Popup Window not Responding

I'm having a problem with a popup window when its displayed by another thread than the main UI thread...

I've created a sample to demonstrate the problem

http://www.mcsdsoftware.com/samples/PopupSample.zip

In a nutshell, I'm using a Timer to simulate an event from an external object:

Code Snippet

public class TimedEventRaiser

{

private System.Timers.Timer timr = new System.Timers.Timer();

public TimedEventRaiser(int TimePeriod)

{

timr = new System.Timers.Timer(TimePeriod);

timr.Elapsed += new System.Timers.ElapsedEventHandler(timr_Elapsed);

timr.Enabled = true;

}

void timr_Elapsed(object sender, System.Timers.ElapsedEventArgs e)

{

timr.Enabled = false;

if (EventRaised != null)

EventRaised();

}

public event delGeneric EventRaised;

}

I create 2 event raisers....

Code Snippet

//Create Event raisers

TimedEventRaiser raiser1 = new TimedEventRaiser(2000);

raiser1.EventRaised += new delGeneric(raiser1_EventRaised);

TimedEventRaiser raiser2 = new TimedEventRaiser(15000);

raiser2.EventRaised += new delGeneric(raiser2_EventRaised);

On the event I create and show the popup

Code Snippet

var PWindow = new frmPopup();

PWindow.Show();

The popup shows fine if I use a test harness and manually call the method to display the form. Something strange is happenning when another thread is in charge however, the form displays, but none of its controls paint properly, and its stuck with the (Not Responding) title caption.

I've tried adding DoEvents() here and there in the code..

Not sure what I'm doing wrong here... any help would be appreciated..

Thanks,

Gavin Stevens

MCPS, MCSD, MCAD, MCNPS

Gavin.Stevens -at- GMail.com

Gavin Stevens  Tuesday, September 23, 2008 4:47 AM
You can't create any windows on a secondary (and temporary) thread such as used by the Elapsed event. Such a thread must stay alive and pump Windows messages, either through Application.Run() or Form.ShowDialog(). This is not advisable, there is nothing to be gained from creating windows on any thread other than the main thread. Well, a splash screen maybe. You'll instantly solve your problem with a System.Windows.Forms.Timer timer.
nobugz  Tuesday, September 23, 2008 9:19 PM
Separate the logic from the UI. Let your class generate an event when the UI needs to respond. It can subscribe to the event, use Control.Invoke() to marshal the method call to the UI thread and create the required UI components.
nobugz  Tuesday, September 23, 2008 9:37 PM
You can't create any windows on a secondary (and temporary) thread such as used by the Elapsed event. Such a thread must stay alive and pump Windows messages, either through Application.Run() or Form.ShowDialog(). This is not advisable, there is nothing to be gained from creating windows on any thread other than the main thread. Well, a splash screen maybe. You'll instantly solve your problem with a System.Windows.Forms.Timer timer.
nobugz  Tuesday, September 23, 2008 9:19 PM

Ok, that makes sense.. In my real application I'm not using any timers, the popup is displayed in response to an event. I used the timer to simulate an event occurring to demonstrate the problem. So while switching to a System.Windows.Forms.Timer may solve my sample problem, it won't solve my actual implementation which doesn't use any timers...

My application is component based using Unity at the core, I have a PopupWindowService which registers to the events of several singleton object in the Unity container. This "PopupWindowService" is a class library, not my main UI, its goal is to handle the popup notifications displayed to the user and to pass along to the corresponding services any events which are generated by the user clicking on the popup's UI.

Most my eventing is generated by an underlying socket which is running on a different thread. The UI thread really isn't present in this component. I had looked at using WPF as a solution as I could use the Dispatcher to handle the pump problem. I would rather make this work in a 2.0 solution because all the other code is 2.0 based.

Any other suggestions?

Gavin Stevens  Tuesday, September 23, 2008 9:30 PM
Separate the logic from the UI. Let your class generate an event when the UI needs to respond. It can subscribe to the event, use Control.Invoke() to marshal the method call to the UI thread and create the required UI components.
nobugz  Tuesday, September 23, 2008 9:37 PM

You can use google to search for other answers

Custom Search

More Threads

• Create instance in starting Form that is Disposed in child form
• Accessing STL Strings
• How Can I bring the Menu list of Recently Opened file in Forms?
• Go To Line
• datakeynames for datagridview
• Tab Alignment control in Windows Forms
• Problem with closing maximized windows in MDI Program
• binding source add event not fire
• How to show a ABOUT Form????????
• Problem with MSDN Example: Add Custom Information To A Treeview Control