469,889 Members | 1,120 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,889 developers. It's quick & easy.

Nested ShowDialog doesn't make the second dialog truely modal??


I'm having weird results with a form that is already displayed modally
(via ShowDialog) displaying a second form via ShowDialog. The last
form is not modal even though it's called with ShowDialog.

For example, given three forms:

Startup
Pop1
Pop2

and this scenario:

Sub Main
Application.Run(new Startup())
End Sub

Class Startup
Sub Whatever
Dim f as new Pop1
f.ShowDialog()
End Sub
End Class

Class Pop1
Sub Whatever
Dim f as new Pop2
f.ShowDialog()
End Sub
End Class
I would expect that when Pop2 is displayed via the second ShowDialog
call, Pop2 should become modal as related to Pop1, but that's not the
case. Both forms Pop1 and Pop2 are modal as related to Startup but
clicking on Startup activates Pop1 and Pop1 is fully interactive.

I can work around the problem by disabling Pop1 before showing Pop2,
but it seems odd that I have to do that. Is there something I'm
misunderstanding about how ShowDialog works? Is there another,
better, workaround?

Thanks,

Sam

Nov 21 '05 #1
6 4721
Hi

It seems that I can not reproduce the problem on my side.
Here is my reproduce code.
If I have any misunderstanding, please feel free to post here.

[startup class]
Public Class Class1
Public Shared Sub Main()
Application.Run(New Form3)
End Sub
End Class

[Form3]
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Dim fm As New Form4
fm.ShowDialog()
End Sub

[Form4]
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Dim fm As New Form ' We note it as A
fm.ShowDialog()
End Sub

If we did not close A, neither Form4 nor Form3 can not activated.

Best regards,

Perter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.

Nov 21 '05 #2
Hi

It seems that I can not reproduce the problem on my side.
Here is my reproduce code.
If I have any misunderstanding, please feel free to post here.

[startup class]
Public Class Class1
Public Shared Sub Main()
Application.Run(New Form3)
End Sub
End Class

[Form3]
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Dim fm As New Form4
fm.ShowDialog()
End Sub

[Form4]
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Dim fm As New Form ' We note it as A
fm.ShowDialog()
End Sub

If we did not close A, neither Form4 nor Form3 can not activated.

Best regards,

Perter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.

Nov 21 '05 #3
Peter,

Thank you for looking into this. I didn't realize it earlier but the
problem is related to threading. Here's the situation (and
reproducible code follows):

Form 1 does a show dialog which launces a threadpool operation which
broadcasts an event which form1 (yes, the original form) catches and
calls another showdialog.

I was told (and research didn't disprove, but couldn't confirm) that
the act of broadcasting an event also handled multi-threading and that
when you broadcast an event the call is made on the appropriate
thread, just like a Control.Invoke.

That appears to be the problem, 'cause if i change the event broadcast
to be a direct Control.Invoke, then the problem goes away. Of course
this isn't an option in the real application (too tight coupling) but
it can lead to a solution.

If there is another option or workaround or if there is something I'm
doing wrong, I'd appreciate the feedback. Also, if you or anyone has
links to documentation on how events are related to multi-threading
(to show my coworker that gave the apparently incorrect information),
that would be helpful.

Thanks,

Sam
Imports System.Threading
Imports System.Windows.Forms

Public Class ShowDialogTest

Public Shared Sub Main()
Application.Run(New Form1)
End Sub
End Class

Public Class Form1
Inherits Form

Private Shared _counter As Integer = 0

Public Sub New()
_counter += 1
Text = "Form " + _counter.ToString()
AddHandler TriggerNew, AddressOf Form1_TriggerNew
End Sub

Private Sub Form1_Click(ByVal sender As Object, ByVal e As
System.EventArgs) Handles MyBase.Click
ThreadPool.QueueUserWorkItem(AddressOf TriggerStart)
End Sub

Public Event TriggerNew As EventHandler

Private Sub TriggerStart(ByVal state As Object)
RaiseEvent TriggerNew(Me, EventArgs.Empty)
' if we change it to not use an event but use Invoke instead,
' then ShowDialog problem is fixed
'Invoke(New EventHandler(AddressOf Form1_TriggerNew))
End Sub

Private Sub Form1_TriggerNew(ByVal sender As Object, ByVal e As
EventArgs)
Dim f As New Form1
f.ShowDialog()
End Sub
End Class


On Thu, 27 Jan 2005 02:43:05 GMT, v-******@online.microsoft.com
("Peter Huang" [MSFT]) wrote:
Hi

It seems that I can not reproduce the problem on my side.
Here is my reproduce code.
If I have any misunderstanding, please feel free to post here.

[startup class]
Public Class Class1
Public Shared Sub Main()
Application.Run(New Form3)
End Sub
End Class

[Form3]
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Dim fm As New Form4
fm.ShowDialog()
End Sub

[Form4]
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Dim fm As New Form ' We note it as A
fm.ShowDialog()
End Sub

If we did not close A, neither Form4 nor Form3 can not activated.

Best regards,

Perter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.


Nov 21 '05 #4
Peter,

Thank you for looking into this. I didn't realize it earlier but the
problem is related to threading. Here's the situation (and
reproducible code follows):

Form 1 does a show dialog which launces a threadpool operation which
broadcasts an event which form1 (yes, the original form) catches and
calls another showdialog.

I was told (and research didn't disprove, but couldn't confirm) that
the act of broadcasting an event also handled multi-threading and that
when you broadcast an event the call is made on the appropriate
thread, just like a Control.Invoke.

That appears to be the problem, 'cause if i change the event broadcast
to be a direct Control.Invoke, then the problem goes away. Of course
this isn't an option in the real application (too tight coupling) but
it can lead to a solution.

If there is another option or workaround or if there is something I'm
doing wrong, I'd appreciate the feedback. Also, if you or anyone has
links to documentation on how events are related to multi-threading
(to show my coworker that gave the apparently incorrect information),
that would be helpful.

Thanks,

Sam
Imports System.Threading
Imports System.Windows.Forms

Public Class ShowDialogTest

Public Shared Sub Main()
Application.Run(New Form1)
End Sub
End Class

Public Class Form1
Inherits Form

Private Shared _counter As Integer = 0

Public Sub New()
_counter += 1
Text = "Form " + _counter.ToString()
AddHandler TriggerNew, AddressOf Form1_TriggerNew
End Sub

Private Sub Form1_Click(ByVal sender As Object, ByVal e As
System.EventArgs) Handles MyBase.Click
ThreadPool.QueueUserWorkItem(AddressOf TriggerStart)
End Sub

Public Event TriggerNew As EventHandler

Private Sub TriggerStart(ByVal state As Object)
RaiseEvent TriggerNew(Me, EventArgs.Empty)
' if we change it to not use an event but use Invoke instead,
' then ShowDialog problem is fixed
'Invoke(New EventHandler(AddressOf Form1_TriggerNew))
End Sub

Private Sub Form1_TriggerNew(ByVal sender As Object, ByVal e As
EventArgs)
Dim f As New Form1
f.ShowDialog()
End Sub
End Class


On Thu, 27 Jan 2005 02:43:05 GMT, v-******@online.microsoft.com
("Peter Huang" [MSFT]) wrote:
Hi

It seems that I can not reproduce the problem on my side.
Here is my reproduce code.
If I have any misunderstanding, please feel free to post here.

[startup class]
Public Class Class1
Public Shared Sub Main()
Application.Run(New Form3)
End Sub
End Class

[Form3]
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Dim fm As New Form4
fm.ShowDialog()
End Sub

[Form4]
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Dim fm As New Form ' We note it as A
fm.ShowDialog()
End Sub

If we did not close A, neither Form4 nor Form3 can not activated.

Best regards,

Perter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.


Nov 21 '05 #5
Hi

Based on my knowledge, Winform control including windows form is not
thread-safe, so in the multithread scenario, we will invoke the call on
the winform thread(i.e. the main thread that show the form) or we will get
unexpected problem. Event handle is kind of callback mechanism, we can
consider event as kind of delegate(function point), the event handler
function will be run on the caller thread. If the event handler function
have nothing to do with UI, that will be fine, but if it has something with
UI(e.g. change the form.text, then here may cause problem and that is why
we suggested call the control.invoke, so that the call will be called on
the thread where the control lie in, i.e. the main thread.

Here are three articles, you may have a look.

Safe, Simple Multithreading in Windows Forms, Part 1
http://msdn.microsoft.com/library/de...us/dnforms/htm
l/winforms06112002.asp

Safe, Simple Multithreading in Windows Forms, Part 2
http://msdn.microsoft.com/library/de...us/dnforms/htm
l/winforms08162002.asp

Safe, Simple Multithreading in Windows Forms, Part 3
http://msdn.microsoft.com/library/de...us/dnforms/htm
l/winforms01232003.asp

Best regards,

Perter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.

Nov 21 '05 #6
Hi

Based on my knowledge, Winform control including windows form is not
thread-safe, so in the multithread scenario, we will invoke the call on
the winform thread(i.e. the main thread that show the form) or we will get
unexpected problem. Event handle is kind of callback mechanism, we can
consider event as kind of delegate(function point), the event handler
function will be run on the caller thread. If the event handler function
have nothing to do with UI, that will be fine, but if it has something with
UI(e.g. change the form.text, then here may cause problem and that is why
we suggested call the control.invoke, so that the call will be called on
the thread where the control lie in, i.e. the main thread.

Here are three articles, you may have a look.

Safe, Simple Multithreading in Windows Forms, Part 1
http://msdn.microsoft.com/library/de...us/dnforms/htm
l/winforms06112002.asp

Safe, Simple Multithreading in Windows Forms, Part 2
http://msdn.microsoft.com/library/de...us/dnforms/htm
l/winforms08162002.asp

Safe, Simple Multithreading in Windows Forms, Part 3
http://msdn.microsoft.com/library/de...us/dnforms/htm
l/winforms01232003.asp

Best regards,

Perter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.

Nov 21 '05 #7

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

5 posts views Thread by Mike | last post: by
1 post views Thread by Frank Rizzo | last post: by
14 posts views Thread by shark | last post: by
1 post views Thread by Waqarahmed | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.