Proposal: Improve ContentDialog API and Prevent Crashes
See original GitHub issueProposal: Improve ContentDialog API and Prevent Crashes (applies to MessageDialog as well)
Multiple ContentDialog instances are not supported which leads to crashes when the app attempts to open the second one. While the framework does not support multiple dialogs, it also does not provide a reliable way for closing/detecting an already open one. This creates a bad combination for application developers.
To make this more robust we need two things:
- Provide a rock-solid API for the app to manage already open ContentDialogs/MessageDialogs
- Allow multiple ContentDialogs (and, if possible and not removed from the platform, MessageDialogs) to be displayed on top of each other (like classic Windows allows) and make it the responsibility of the App to manage them correctly. This is only to prevent crashes when the app doesn’t manage things correctly – it’s a fail-safe for robustness.
Note: Number 2 would be difficult to do on mobile platforms with the Uno architecture. (We’ll see how WinUI evolves for Surface Duo!)
Summary
- Provide a rock-solid API for the app to manage already open ContentDialogs.
// As named, returns true if a ContentDialog is already open
Application.IsContentDialogOpen
// Will not directly close the ContentDialog but will synchronously return a reference
// to it so the application developer can decide how best to close it.
Application.GetOpenContentDialog()
// Overload to ShowAsync() to specify what to do if a ContentDialog is already open
ContentDialog.ShowAsync(HandleExistingDialogOption existingDialogOption)
enum HandleExistingDialogOption
{
/// <summary>
/// Closes any already open dialog and returns ContentDialogResult.None
/// (or an empty command for MessageDialog)
/// </summary>
CloseExisting,
/// <summary>
/// Does not show the new dialog and immediately returns ContentDialogResult.None
/// (or an empty command for MessageDialog)
/// </summary>
DoNotShow,
/// <summary>
/// Dialog will be enqueued and shown once all previous dialogs are closed.
/// </summary>
Enqueue
}
- As stated, allow multiple ContentDialogs to be displayed on top of each other
Remove the platform restriction of only one ContentDialog being open. Also definitely prevent a hard-crash if the application attempt to open a second. Two ContentDialogs is understood to be bad practice but there are some edge cases this helps protect against. Number 1 is still the primary solution.
Rationale
Currently, only one content dialog can be open at a time in the UI. This makes sense as it’s meant to be blocking waiting for user input.
However, there are some scenarios where notifications are being sent from the backend to the frontend (not as a result of direct user input) and they should be displayed in a blocking content dialog to the user.
The problem occurs when multiple notifications are sent from the backend and the user hasn’t yet closed the first one. In this case the app crashes when it tries to create the second ContentDialog. As a work around, apps can attempt to close dialogs themselves; however, this does not always work. If a request to open a content dialog comes fast enough a crash still occurs.
Applications should not crash so easily when opening a ContentDialog. Work-arounds such as the example code below are not reliable as they are somewhat dependent on timing.
public static bool IsContentDialogOpen(Window window = null)
{
// By default use the current window
if (window == null)
{
window = Window.Current;
}
// Get all open popups in the window. A ContentDialog is a popup.
var popups = VisualTreeHelper.GetOpenPopups(window);
foreach (var popup in popups)
{
if(popup.Child is ContentDialog)
{
// A content dialog is open
return (true);
}
}
return (false);
}
or
var popups = VisualTreeHelper.GetOpenPopups(Window.Current);
foreach(var popup in popups)
{
if (popup.Child is ContentDialog)
{
((ContentDialog)popup.Child).Hide();
}
}
Issue Analytics
- State:
- Created 4 years ago
- Reactions:16
- Comments:18 (17 by maintainers)

Top Related StackOverflow Question
@mrlacey We could talk about application architecture endlessly but that would be a bit out of scope I think. However, since you are curious here is the full scenario:
So I try to close any already open ContentDialogs but the APIs to do so just are not there. Eventually the app will crash if requests are coming fast enough. I do of course agree that showing multiple ContentDialogs is bad but there are some edge cases as @yaichenbaum also mentions.
The point is we can’t adequately manage ContentDialogs because the API just isn’t there:
You can’t have the platform hard-crash when a second ContentDialog is being opened and then not provide an API to manage ContentDialogs (instead relying on the user to do it). On top of that – the limit of one ContentDialog open should not be enforced by crashing… classic Windows or WPF never did that. The framework should allow multiple ContentDialogs to be open for the cases where the app doesn’t manage them correctly (assuming they get the API to do so).
Crashes are bad, ContentDialogs should not be this fragile.
I’m going to reword my proposal a bit asking for the API to manage ContentDialogs and also for the app not to crash when a second is opened. I think we need both to robustly fix this for application developers.
I have a Notepad app using a content dialog to let users jump to a different line. If the user closes the notepad app when the dialog is still open, it’ll crash when the save dialog is shown. I don’t need two dialogs open at once but the API should handle scenarios like this properly instead of crashing.