There are many ways to approach it, and the choice may depend on your skills, requirements and preferences.
My personal choice is to avoid using dialog boxes at all, as they are poorly suited for users ( evil ). There are alternative solutions, such as displaying a separate screen / page with a user interface requiring the user to enter some input when it is really necessary, or displaying a modeless pop-up window somewhere on the side / edge / corner if the user input is optional and hides it in a moment or some other notification that does not interrupt the flow of users.
If you do not agree or do not have the time, resources or skills to implement an alternative, you can create a kind of wrapper around MessageDialog.ShowAsync () to call in a queue or ignore new requests while the dialog is already shown.
This class has extension methods that allow you to either ignore a new show request when another dialog is already displayed, or request queues:
/// <summary> /// MessageDialog extension methods /// </summary> public static class MessageDialogExtensions { private static TaskCompletionSource<MessageDialog> _currentDialogShowRequest; /// <summary> /// Begins an asynchronous operation showing a dialog. /// If another dialog is already shown using /// ShowAsyncQueue or ShowAsyncIfPossible method - it will wait /// for that previous dialog to be dismissed before showing the new one. /// </summary> /// <param name="dialog">The dialog.</param> /// <returns></returns> /// <exception cref="System.InvalidOperationException">This method can only be invoked from UI thread.</exception> public static async Task ShowAsyncQueue(this MessageDialog dialog) { if (!Window.Current.Dispatcher.HasThreadAccess) { throw new InvalidOperationException("This method can only be invoked from UI thread."); } while (_currentDialogShowRequest != null) { await _currentDialogShowRequest.Task; } var request = _currentDialogShowRequest = new TaskCompletionSource<MessageDialog>(); await dialog.ShowAsync(); _currentDialogShowRequest = null; request.SetResult(dialog); } /// <summary> /// Begins an asynchronous operation showing a dialog. /// If another dialog is already shown using /// ShowAsyncQueue or ShowAsyncIfPossible method - it will wait /// return immediately and the new dialog won't be displayed. /// </summary> /// <param name="dialog">The dialog.</param> /// <returns></returns> /// <exception cref="System.InvalidOperationException">This method can only be invoked from UI thread.</exception> public static async Task ShowAsyncIfPossible(this MessageDialog dialog) { if (!Window.Current.Dispatcher.HasThreadAccess) { throw new InvalidOperationException("This method can only be invoked from UI thread."); } while (_currentDialogShowRequest != null) { return; } var request = _currentDialogShowRequest = new TaskCompletionSource<MessageDialog>(); await dialog.ShowAsync(); _currentDialogShowRequest = null; request.SetResult(dialog); } }
Test
// This should obviously be displayed var dialog = new MessageDialog("await ShowAsync", "Dialog 1"); await dialog.ShowAsync(); // This should be displayed because we awaited the previous request to return dialog = new MessageDialog("await ShowAsync", "Dialog 2"); await dialog.ShowAsync(); // All other requests below are invoked without awaiting // the preceding ones to complete (dialogs being closed) // This will show because there is no dialog shown at this time dialog = new MessageDialog("ShowAsyncIfPossible", "Dialog 3"); dialog.ShowAsyncIfPossible(); // This will not show because there is a dialog shown at this time dialog = new MessageDialog("ShowAsyncIfPossible", "Dialog 4"); dialog.ShowAsyncIfPossible(); // This will show after Dialog 3 is dismissed dialog = new MessageDialog("ShowAsyncQueue", "Dialog 5"); dialog.ShowAsyncQueue(); // This will not show because there is a dialog shown at this time (Dialog 3) dialog = new MessageDialog("ShowAsyncIfPossible", "Dialog 6"); dialog.ShowAsyncIfPossible(); // This will show after Dialog 5 is dismissed dialog = new MessageDialog("ShowAsyncQueue", "Dialog 7"); dialog.ShowAsyncQueue(); // This will show after Dialog 7 is dismissed dialog = new MessageDialog("ShowAsyncQueue", "Dialog 8"); dialog.ShowAsyncQueue();
source share