Dialogs

Tip

This article covers Uno-specific information for dialog controls in Uno Platform. For a full description of the feature and instructions on using it, see Dialog controls | Microsoft Learn.

  • The Microsoft.UI.Xaml.Controls.ContentDialog class provides a XAML-based and highly customizable user dialog.
  • The Windows.UI.Popups.MessageDialog represents a legacy dialog which provides less control over UI.

Using ContentDialog

The recommended way to display user dialogs is via the Microsoft.UI.Xaml.Controls.ContentDialog class.

ContentDialog noWifiDialog = new ContentDialog
{
    Title = "No WiFi connection",
    Content = "Check your connection and try again.",
    CloseButtonText = "OK"
};

// Make sure to set the XamlRoot!
noWifiDialog.XamlRoot = anyLoadedControl.XamlRoot;

ContentDialogResult result = await noWifiDialog.ShowAsync();

It is crucial to set the XamlRoot property before calling ShowAsync. This way the dialog will become associated with the visual tree. XamlRoot can be retrieved from any loaded control in your window (e.g. a Button, your Page, etc.).

Warning

Only one ContentDialog can be open per thread at a time. Attempting to open two ContentDialogs will throw an exception, even if they are trying to open in separate AppWindows.

Opening a ContentDialog from a Model/ViewModel

When you want to open a ContentDialog from a Model or ViewModel, you can pass the XamlRoot from the view to the model or view model by creating a service (e.g., IXamlRootProvider) that is initialized at the start of the app with the XamlRoot of the main window.

Here is a more detailed example of how to display a ContentDialog with result handling:

private async Task DisplayDeleteFileDialog()
{
    ContentDialog deleteFileDialog = new ContentDialog
    {
        Title = "Delete file permanently?",
        Content = "If you delete this file, you won't be able to recover it. Do you want to delete it?",
        PrimaryButtonText = "Delete",
        CloseButtonText = "Cancel"
    };

    deleteFileDialog.XamlRoot = anyLoadedControl.XamlRoot;

    ContentDialogResult result = await deleteFileDialog.ShowAsync();

    // Delete the file if the user clicked the primary button.
    // Otherwise, do nothing.
    if (result == ContentDialogResult.Primary)
    {
        // Delete the file.
    }
    else
    {
        // The user clicked the CloseButton, pressed ESC, Gamepad B, or the system back button.
        // Do nothing.
    }
}

If you are using the MVVM pattern, you can use the AsyncRelayCommand from the Uno Platform to bind the command to the dialog display method. Here is an example of how to bind the command to the dialog display method in the ViewModel:

public MainViewModel()
{
    DisplayDeleteFileDialogCommand = new AsyncRelayCommand(DisplayDeleteFileDialog);
}

// ...

public ICommand DisplayDeleteFileDialogCommand { get; }

private async Task DisplayDeleteFileDialog()
{
    // ...
}

To bind the command to a button in your view, you can use the following code snippets:

<Button Content="Delete file" Command="{Binding DisplayDeleteFileDialogCommand}" />

If you are using Uno.Extensions Navigation, you can utilize its features to display a dialog. For more information, check out this documentation: Dialogs with Uno.Extensions.Navigation.

Considering adding a dialog to your app? Check out our comprehensive video for detailed guidance on the implementation:

Customize a ContentDialog

You can use various properties to customize its display and also provide a custom XAML-based content for it. For more information, see ContentDialog Class | Microsoft Learn.

In order for your custom dialog to follow the Fluent design, it's important that you add the following line in the constructor of your dialog:

Style = Application.Current.Resources["DefaultContentDialogStyle"] as Style;

Your dialog will look similar to this dialog:

Content dialog with style sample

If you omit this line, your dialog will look like this:

Content dialog without style sample

Overlay Background (iOS/Android)

You can override the overlay background by adding the following resources to the application resources:

<SolidColorBrush x:Key="ContentDialogLightDismissOverlayBackground" Color="#99000000" />
Note

There is no specific key to override for this other than SystemControlPageBackgroundMediumAltMediumBrush on Windows, see Changing the Overlay background color for ContentDialog question on StackOverflow.

Using MessageDialog

Warning

MessageDialog is a legacy API that is no longer officially supported. If possible, please use ContentDialog instead.

For existing applications that rely on MessageDialog, updating to Uno Platform 5.2 and newer requires you to associate the MessageDialog with a window before it is displayed. This can be done via the WinRT.Interop APIs:

var dialog = new MessageDialog();

// ...

// Get the current window's HWND by passing a Window object
var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(window);
// Associate the HWND with the dialog
WinRT.Interop.InitializeWithWindow.Initialize(dialog, hwnd);

await dialog.ShowAsync();

Using native or XAML-based UI for MessageDialog

Uno Platform targets offer two different display modes for MessageDialog. To switch between them, you can use the UseNativeDialog.