Introduction

What can you do if you would like to display a modal / blocking dialog in WPF? By default, there is the possibility to use the Window.ShowDialog() method. This has the disadvantage that a completely new "Windows"-window will be created which is not part of our main application window (which again has several disadvantages that I don’t want to discuss here). I would like to present an alternative solution.

As shown in the image, we would like to have a half transparent overlay with some kind of content (here, just for example, we use a simple text message, but we could also display other controls).

The ModalDialog control

The functionality and design is outsourced in a User Control. The XAML of this control is quite simple: we have the half transparent border that we use as our overlay, the TextBlock to display our message, and two Buttons for OK / Cancel.

Of course, it is still not clear how the "modal" or "blocking" behavior of the dialog is achieved. But how is that done? That’s a little bit tricky (you could also say "hacky"
). We have the following problem: "blocking" or "modal" means that the instruction pointer of our execution should remain at its position as long as the dialog is shown, and when the dialog is closed, it should continue. To achieve this, we would have to suspend the calling thread (typically the UI thread). If it is suspended, an interaction with our dialog will also be impossible because it is suspended, too. This is because WPF relies on a single thread model, which means it is impossible to run UI elements in another thread different from the thread of our main window. So we have to use a little hack here (I’m really not a friend of hacks, but here, it’s absolutely necessary).

When the dialog is shown, we start a loop in which we suspend the calling thread (typically the UI thread) for a short time, and we also advise the WPF dispatcher to process the messages (mouse click, movements, keystrokes, repaint, etc.) that occur in the sleeping time. If we choose a sleep time that is small enough, for the user it seems that the application is running fluently. Attention: If you would like to display elements in our dialog that have a lot of "animation" stuff on it, we will run into problems. If we just use some simple elements, it’s OK.

Notice that the dialog needs a reference to the element that "holds" the complete content of the window. In our case, this is the grid with the name "ModalDialogParent". This is important so that the dialog can disable it when it is shown (otherwise, the user could cycle with "tab" through the elements of the window).

I think you simply proposed a different solution. Your pattern is asynchronous (non-blocking), mine is synchronous (blocking). There are scenarios where asynchronous calls with a callback will not fit your requirements, unfortunately.

Blocking the UI thread - as you mentioned - might be a bad idea in the most cases (as usually the app runs in that thread and blocking the UI thread means blocking your whole application). But to generalize that it's _always_ a "very bad idea" is - from my point of view - not always correct: you have to check your requirements and figure out what you want to achieve. In this case here, blocking the UI thread (unfortunately in WPF we have only one UI thread) is the desired behavior.

Loic is right - it *is* a bad idea to block the UI thread (you always have just one, that's not a specific WPF feature), as it prevents redrawing your UI. This will most likely lead to nasty side effects in a variety of use cases. If you are willing to introduce such a hack (your words ) - would you care to elaborate the upside of blocking the UI's own thread?

if you had a closer look at my the code, you would see that the UI thread is refreshed cycically from another thread using the dispatcher of the application so that the message queue is processed and thus the UI _is_ redrawn. The fact that it is only redrawn every x milliseconds, _this_ I called a hack. If you had a closer look at the code in the link you posted, you would see that there, basically the same thing is done by using a dispatcher timer to update his progress bar cycicaly.

The timer in the sample only refreshes the progress bar but the UI thread itself is never affected - so this really isn't the same thing (and I had infact a look at the code ).

I don't want to be a pain here - I'm just interested to know why you chose your pattern - after all, you even published it here on CP. You are mentioning disadvantages you don't want to discuss, but in order to promote an alternative design that even blocks the UI thread, you shouldn't wonder if people would infact want to hear your reasons

1) The solution you posted is definitely an alternative solution. That solution uses the ShowDialog() method which is basically doing this: It blocks the execution of the thread from which it was invoked. If the dialog is closed, the execution continues. Perfect! This is what I needed: It's a synchronous call to display a dialog.

2) I couldn't use ShowDialog because it is not possible to use a WPF control inside the main window, but only a completely new window as the dialog content. In my application, I needed the ability to host quite complex controls in the modal dialog which had to be in the main window so that they were arranged by the layout system.

3) The mentioned disadvantages refered to the posted _asynchronous_ solution, which means: you invoke the dialog, but you don't wait until it is closed. Instead, you continue the execution and a delegate is called when the dialog is closed. In most cases, this will fit the requirements - so use it! In my scenario, I had - unfortunately - problems with this pattern, because: To decouple our components, we implemented a small synchronous message/event bus. Components had the ability to react to certain messages, but the problem here was that if you needed user interaction, we had to block the execution of this message until the user made his decision. This cannot be achieved by using the asynchronous solution.