I’m looking for a good way to implement a truly modal dialog in Silverlight 5. Every example that I find that claims to create a modal dialog really isn’t modal in that the calling code waits until the dialog is closed.
I realize this is a challenge because we can’t actually block the UI thread because it must be running in order for the dialog (ChildWindow) to function correctly. But, with the addition of the TPL in SL5 and the higher level of adoption Silverlight has seen over the past few years, I’m hoping someone has found a way around this.
A good representative scenario I am trying to solve is an action (say clicking a button or menu item) that displays a login dialog and must wait for the login to complete before proceeding.
Our specific business case (whether logical or not) is that the application does not require user authentication; however, certain functions require “Manager” access. When the function is accessed (via button click or menu item selected, etc), and the current user is not a manager, we display the login dialog. When the dialog closes, we check the user’s authorization again. If they are not authorized, we display a nice message and reject the action. If they are authorized, we continue to perform the action which typically involves changing the current view to something new where the user can do whatever it is they requested.
For the sake of closure…
What I ended up with is a new TPL-enabled DialogService with methods like:
The method creates an instance of the dialog (ChildWindow), attaches a handler to the Closed event and calls the Show method. Internally, it uses a TaskCompletionSource<Boolean?> to return a Task to the caller. In the Closed event handler, the DialogResult is passed to the TrySetResult() method of the TaskCompletionSource.
This lets me display the dialog in a typical async way:
Or, I could block using the Task.Wait() method – although this is problematic because, as I mentioned in the original post, it blocks the UI thread, so even the dialog is frozen.
Still not a true modal dialog, but a little bit closer to the behavior I am looking for. Any improvements or suggestions are still appreciated.