3

So I have a menu form for my application, let us call it the grandparent. The user clicks a button, and it calls another form, let's call it the parent form, with form.show(). Because I used show(), and not showdialog(), I can play around with either form now.

Then, in the parent form, I call a third form, let's call it child, with a form.showdialog(). I want the user to have to close the child form before being able to do anything with the parent form, and that is exactly what happens. The problem is that now I can't use the grandparent form either, it is locked until I close the child form, and I don't want it to be.

In other words, I want the child form to be modal, but only in respect the parent form, not the grandparent form. Can such a thing be done?

Davide Piras
  • 43,984
  • 10
  • 98
  • 147
  • 1
    Modal is bad. It usually means developers are too lazy to imagine I have a different workflow than the only one they thought of. – Dan Abramov Jul 05 '11 at 21:49
  • It is very important that it works this way, this answer explains why: http://stackoverflow.com/questions/5181777/c-application-doevents/5183623#5183623 You can break it by pinvoking EnableWindow() in a method you start with Control.BeginInvoke() before ShowDialog(). – Hans Passant Jul 05 '11 at 22:01
  • Thank you for the link Hans, that was very interesting. – Scott Hagie Jul 05 '11 at 23:38

2 Answers2

3

if you can live with the fact that your parent and child forms live on another thread than you grandparent (so you will have to invoke when you need to use controls on the other thread) you could start a 2nd UI thread for your parent form ...

when the modal dialog blocks the message queue of the parent forms UI thread, the grandparents UI thread will still have its own non-blocked message queue ...

so instead of calling

new ParentForm().Show();

somewhere in the code of your grandparent-form call

new System.Threading.Thread(
                    delegate() {
                        Application.Run(new ParentForm());
                    }
                ).Start();
DarkSquirrel42
  • 10,167
  • 3
  • 20
  • 31
  • Thank you very much, that worked beautifully. The grandparent and parent forms don't really interact at all, so another thread works just fine for me. – Scott Hagie Jul 05 '11 at 23:37
  • Note - the UI queue is not blocked, .Net disables all the other program's windows on purpose to prevent the utter mayhem that would be reeked on most programs if this were permitted. – FastAl Jul 22 '11 at 14:07
0

ShowDialog() blocks the UI thread, so I don't think it can be done easily. You could launch the child form in a new process... but that's pretty drastic.

You could disable the parent form manually (disable all controls - put everything on a UserControl or a Panel and just disable that). Then you could just throw up a message if the user happens to click on the parent form, saying "please close first". When the child form closes, re-enable the parent.

If you want to make sure the child form stays visible, set the TopMost property, but be wary of doing that since it can really annoy the user.

Igby Largeman
  • 16,495
  • 3
  • 60
  • 86