2
votes

I have a WPF application. The main window of this application has a button. I am opening a WinForms modal dialog in a separate thread when this button is clicked. The trouble I am having is that the dialog does not behave like a modal i.e it is still possible to switch focus to the main window, whereas, I require to allow focus on the newly opened dialog and it should not be possible to select the main window.

Note: I cannot move the modalDialog.ShowDialog(); outside of the delegate because the dialog form creates controls dynamically and this means that these controls must remain on the thread that it was created. To be more clear, if I move the modalDialog.ShowDialog(); outside I will get an exception like so:

Cross-thread operation not vaild: Control 'DynamicList' accessed from a thread other than the one it was created on.

Any ideas as to how I might make the form behave as a modal?

Here is the code:

private void button1_Click(object sender, RoutedEventArgs e)
{
   DoSomeAsyncWork();
}

private void DoSomeAsyncWork()
{ 
  var modalDialog = new TestForm();
  var backgroundThread = new Thread((
     delegate()
     {
          // Call intensive method that creates dynamic controls
          modalDialog.DoSomeLongWaitingCall();
          modalDialog.ShowDialog();
     }
   ));
  backgroundThread.Start();
}
1
You can't make this work. Use Dispatcher.Invoke() to have the ShowDialog() call executed on the main thread. - Hans Passant
If I do this I get the following error: "Cross-thread operation not vaild: Control 'DynamicList' accessed from a thread other than the one it was created on." because I have crated objects on the background thread. - fin
Only create the data that the form needs on the worker thread. All ui needs to be done on the ui thread. No exceptions. Pun intended. - Hans Passant

1 Answers

2
votes

You should always create controls on the UI thread. If you do that, calling ShowDialog() through Dispatcher should work.