1
votes

I am working on a WPF application where multiple windows can be present at one time. The Windows are shown using the Dispatcher and thus each Window has its own UI Thread, according to the WPF Threading Model https://msdn.microsoft.com/en-us/library/ms741870(v=vs.100).aspx . The below code is from this link.

         private void ThreadStartingPoint()
         {
             Window1 tempWindow = new Window1();
             tempWindow.Show();       
             System.Windows.Threading.Dispatcher.Run();
         }

"This method is the starting point for the new thread. We create a new window under the control of this thread. WPF automatically creates a new Dispatcher to manage the new thread."

Is it possible to show a Window using ShowDialog(), that will be modal across all the Windows in my application? Meaning that a user would not be able to interact with any of the Windows while the dialog is shown.

My thought is that this is not possible since the Window can only be shown on one UI Thread and the other Windows will still be able to interact.

One solution I attempted is to set the owner to the MainWindow of the app. This throws an InvalidOperationException. "The calling thread cannot access this object because a different thread owns it."

        DialogWindow dialog = new DialogWindow();
        dialog.Owner = App.Current.MainWindow;
        dialog.ShowDialog();
        System.Windows.Threading.Dispatcher.Run();
1
did you try : tempWindow.ShowDialog(); ?Dark Templar
The first code block is used to show the Windows in the application which are not dialogs. The second code block with DialogWindow is where I am having an issue. Sorry for any confusion.Allan B.

1 Answers

0
votes

Is it possible to show a Window using ShowDialog(), that will be modal across all the Windows in my application?

Only if all of those windows are owned by a single thread.

Fact is, the core of your problem is that you have more than one UI thread. As the documentation page you referred to says:

multithreaded programs…should be avoided when single-threaded solutions exist.

This isn't referring strictly to programs with multiple UI threads. They really mean all types of multithreaded programs. But it's especially true for the scenario of multiple UI threads.

The same document also says:

It is perfectly acceptable for one Thread/Dispatcher combination to manage multiple windows

The fact that you have multiple windows that can be present at one time in no way suggests that you should be starting a new thread for each window. And indeed, starting a new thread for each window (or even more than one dispatcher thread at all) should be avoided at all costs.

Modal behavior for windows is implemented on a per-thread basis. Each thread that owns a window has a message pump loop that dispatches window messages to each window. When a window is displayed modally, it provides its own message pump loop that takes over temporarily for the thread's main loop, and intercepts user input messages that would normally be dispatched to other windows.

The modal window's message pump loop never sees the window messages that are sent to windows owned by other threads, and so never has the opportunity to intercept them. It cannot block the input to those other windows.

The best way to get things to work as you say you want them to work is to stop creating new threads for your new windows. Just use the original UI thread for all of your windows, and then modal dialogs will work just as you want.