Note
The Dialog is dependant on IDialogService
and MudDialogProvider
Check the Installation page for instructions regarding default setup.
Usage
Suppose you define a MudDialog
in TermsOfServiceDialog.razor
.
To show the dialog you simply call:
DialogService.Show<
TermsOfServiceDialog
>("Terms");
@inject IDialogService DialogService <MudButton @onclick="OpenDialogAsync" Variant="Variant.Filled" Color="Color.Primary"> Open Simple Dialog </MudButton>
@code { private Task OpenDialogAsync() { var options = new DialogOptions { CloseOnEscapeKey = true }; return DialogService.ShowAsync<DialogUsageExample_Dialog>("Simple Dialog", options); } }
Configuration
The dialog's default behavior can be changed in two ways, either globally with parameters in the <MudDialogProvider/>
or pass down the DialogOptions
class when you open the dialog.
Global Settings
In the file where you added <MudDialogProvider/>
, we can pass down different options as parameters. See installation page for more information regarding this.
<MudDialogProvider FullWidth="true" MaxWidth="MaxWidth.ExtraSmall" CloseButton="true" BackdropClick="false" NoHeader="true" Position="DialogPosition.Center" CloseOnEscapeKey="true" BackgroundClass="my-custom-class"/>
Per Dialog
Below we pass along the DialogOptions class when we open the dialog, this can be done per dialog or you can predefine a bunch of them that you use for specific cases in your system.
@inject IDialogService Dialog <MudButton OnClick="@(() => OpenDialogAsync(_maxWidth))">Open MaxWidth Dialog</MudButton> <MudButton OnClick="@(() => OpenDialogAsync(_closeButton))" Color="Color.Primary">Close Button Dialog</MudButton> <MudButton OnClick="@(() => OpenDialogAsync(_noHeader))" Color="Color.Secondary">No header Dialog</MudButton> <MudButton OnClick="@(() => OpenDialogAsync(_backdropClick))" Color="Color.Tertiary">Disable backdrop dialog</MudButton> <MudButton OnClick="@(() => OpenDialogAsync(_fullScreen))" Color="Color.Info">Full Screen Dialog</MudButton> <MudButton OnClick="@(() => OpenDialogAsync(_topCenter))" Color="Color.Success">Top Center Dialog</MudButton>
@code { private readonly DialogOptions _maxWidth = new() { MaxWidth = MaxWidth.Medium, FullWidth = true }; private readonly DialogOptions _closeButton = new() { CloseButton = true }; private readonly DialogOptions _noHeader = new() { NoHeader = true }; private readonly DialogOptions _backdropClick = new() { BackdropClick = false }; private readonly DialogOptions _fullScreen = new() { FullScreen = true, CloseButton = true }; private readonly DialogOptions _topCenter = new() { Position = DialogPosition.TopCenter }; private Task OpenDialogAsync(DialogOptions options) { return Dialog.ShowAsync<DialogUsageExample_Dialog>("Custom Options Dialog", options); } }
From dialog
The title and the options can also be modified from the dialog component itself by calling SetTitle
and SetOptions
on the MudDialogInstance
object.
@inject IDialogService DialogService <MudButton OnClick="OpenDialogAsync" Variant="Variant.Filled" Color="Color.Primary"> Options Dialog </MudButton>
@code { private Task OpenDialogAsync() { return DialogService.ShowAsync<DialogSetOptionsExample_Dialog>("Options Dialog"); } }
Templating and Passing Simple Data
In this section, we will demonstrate how you can build one dialog and reuse it for multiple purposes.
@inject IDialogService DialogService <MudButton @onclick="DeleteUserAsync" Variant="Variant.Filled" Color="Color.Error">Delete Records</MudButton> <MudButton @onclick="ConfirmAsync" Variant="Variant.Filled" Color="Color.Success">Remove Email</MudButton> <MudButton @onclick="DownloadAsync" Variant="Variant.Filled" Color="Color.Warning">Slow Computer</MudButton>
@code { private Task DeleteUserAsync() { var parameters = new DialogParameters<DialogTemplateExample_Dialog> { { x => x.ContentText, "Do you really want to delete these records? This process cannot be undone." }, { x => x.ButtonText, "Delete" }, { x => x.Color, Color.Error } }; var options = new DialogOptions() { CloseButton = true, MaxWidth = MaxWidth.ExtraSmall }; return DialogService.ShowAsync<DialogTemplateExample_Dialog>("Delete", parameters, options); } private Task ConfirmAsync() { var parameters = new DialogParameters<DialogTemplateExample_Dialog> { { x => x.ContentText, "Are you sure you want to remove thisguy@emailz.com from this account?" }, { x => x.ButtonText, "Yes" }, { x => x.Color, Color.Success } }; return DialogService.ShowAsync<DialogTemplateExample_Dialog>("Confirm", parameters); } private Task DownloadAsync() { var parameters = new DialogParameters<DialogTemplateExample_Dialog> { { x => x.ContentText, "Your computer seems very slow, click the download button to download free RAM." }, { x => x.ButtonText, "Download" }, { x => x.Color, Color.Info } }; return DialogService.ShowAsync<DialogTemplateExample_Dialog>("Slow Computer Detected", parameters); } }
Passing Data
Here is a little more advanced use case. We will use the same dialog but feed it with different server data and then mimic a delete operation.
Server1
Server2
Server3
Server4
@using MudBlazor.Examples.Data.Models @inject IDialogService DialogService <div class="d-flex flex-wrap"> @foreach (var item in Servers) { <MudPaper Class="d-flex align-center pa-2 mx-2 my-2"> <MudText>@item.Name</MudText> <MudButton Variant="Variant.Text" Color="Color.Error" OnClick="@((e) => DeleteServerAsync(item))">Delete</MudButton> </MudPaper> } </div>
@code { private async Task DeleteServerAsync(Server server) { var parameters = new DialogParameters<DialogPassingDataExample_Dialog> { { x => x.Server, server } }; var dialog = await DialogService.ShowAsync<DialogPassingDataExample_Dialog>("Delete Server", parameters); var result = await dialog.Result; if (!result.Canceled) { //In a real world scenario we would reload the data from the source here since we "removed" it in the dialog already. Guid.TryParse(result.Data.ToString(), out Guid deletedServer); Servers.RemoveAll(item => item.Id == deletedServer); } } //Pretend we are loading this data from a database or API public List<Server> Servers { get; } = new List<Server> { new Server{ Id = Guid.NewGuid(), Name = "Server1", Location = "Denmark", IpAddress = "193.254.123.1" }, new Server{ Id = Guid.NewGuid(), Name = "Server2", Location = "Sweden", IpAddress = "127.0.0.1" }, new Server{ Id = Guid.NewGuid(), Name = "Server3", Location = "Russia", IpAddress = "173.164.2.1" }, new Server{ Id = Guid.NewGuid(), Name = "Server4", Location = "Germany", IpAddress = "193.168.1.1" }, }; }
Scrollable Dialog
Quick example on how content that exeeds the available height becomes scrollable.
@inject IDialogService DialogService <MudButton OnClick="OpenDialogAsync" Variant="Variant.Filled" Color="Color.Primary"> Scrollable Dialog </MudButton>
@code { private bool _licenseAccepted = false; private async Task OpenDialogAsync() { var dialog = await DialogService.ShowAsync<DialogScrollableExample_Dialog>("MudBlazor License"); var result = await dialog.Result; if (!result.Canceled) { _licenseAccepted = (bool)(result.Data ?? false); } } }
Blurry Dialog
Dialog background can be changed via BackgroundClass
dialog option.
@inject IDialogService DialogService <MudButton @onclick="OpenDialogAsync" Variant="Variant.Filled" Color="Color.Primary"> Open Simple Dialog </MudButton> <style> .my-custom-class { backdrop-filter: blur(10px); } </style>
@code { private Task OpenDialogAsync() { var options = new DialogOptions { BackgroundClass = "my-custom-class" }; return DialogService.ShowAsync<DialogBlurryExample_Dialog>("Simple Dialog", options); } }
Inlining Dialog
You can inline MudDialog
directly in another component which, of course, makes most sense for small dialogs that are not re-used somewhere else.
The advantage is that you can easily share code and data between dialog and owning component via bindings.
This example also shows how to override the dialog title with a render fragment.
<div class="d-flex"> <MudButton OnClick="OpenDialog" Variant="Variant.Filled" Color="Color.Primary"> Edit rating </MudButton> <MudRating SelectedValue="_rating" Disabled="true" Class="mt-1 ml-3" /> </div> <MudDialog @bind-Visible="_visible" Options="_dialogOptions"> <TitleContent> <MudText Typo="Typo.h6"> <MudIcon Icon="@Icons.Material.Filled.Edit" Class="mr-3" /> Edit rating </MudText> </TitleContent> <DialogContent> <p>How awesome are inline dialogs?</p> <MudRating @bind-SelectedValue="_rating" Class="mt-3" /> </DialogContent> <DialogActions> <MudButton Variant="Variant.Filled" Color="Color.Primary" OnClick="Submit" Class="px-10">Close</MudButton> </DialogActions> </MudDialog>
@code { private bool _visible; private int _rating; private readonly DialogOptions _dialogOptions = new() { FullWidth = true }; private void OpenDialog() => _visible = true; private void Submit() => _visible = false; }
Nested Inline Dialogs
You can inline a MudDialog
within another MudDialog
, even in another inline dialog. This example shows both ways of nesting
an inline dialog.
@inject IDialogService DialogService <MudButton Variant="Variant.Filled" Color="Color.Primary" OnClick="Open">Open Inline</MudButton> <MudButton Variant="Variant.Filled" Color="Color.Primary" OnClick="Open2Async">Open With Show</MudButton> @*Outer inline dialog*@ <MudDialog @bind-Visible="_visible"> <DialogContent> <MudText>Hi There, I'm an inline dialog!</MudText> <MudButton Variant="Variant.Filled" Color="Color.Tertiary" OnClick="OpenNested">Open Nested</MudButton> @*Nested inline dialog*@ <MudDialog @bind-Visible="_nestedVisible"> <DialogContent> <MudText Class="nested">Nested inline dialog!</MudText> </DialogContent> <DialogActions> <MudButton Color="Color.Primary" OnClick="CloseNested">Close</MudButton> </DialogActions> </MudDialog> </DialogContent> <DialogActions> <MudButton Color="Color.Primary" OnClick="Close">Close</MudButton> </DialogActions> </MudDialog>
@code { private bool _visible; private bool _nestedVisible; private void Open() => _visible = true; private void Close() => _visible = false; private void OpenNested() => _nestedVisible = true; private void CloseNested() => _nestedVisible = false; @*Open a non-inline dialog component that nests an inline dialog*@ private Task Open2Async() => DialogService.ShowAsync<DialogNestedInlineExample_Dialog>(); }
Nested Dialogs and Cancel All
It is possible to open multiple dialogs at the same time.
This example also shows how to open a second dialog and cancel all dialogs at once.
@inject IDialogService DialogService <MudButton @onclick="OpenDialogAsync" Variant="Variant.Filled" Color="Color.Primary"> Open Simple Dialog </MudButton>
@code { private Task OpenDialogAsync() { var options = new DialogOptions { CloseOnEscapeKey = true }; return DialogService.ShowAsync<DialogNestedExample_Dialog>("First Level Dialog", options); } }
@inject IDialogService DialogService <MudButton @onclick="OpenDialogAsync" Variant="Variant.Filled" Color="Color.Primary"> Open Dialog </MudButton>
@code { private Task OpenDialogAsync() { var options = new DialogOptions { CloseOnEscapeKey = true }; return DialogService.ShowAsync<DialogKeyboardNavigationExample_Dialog>("Simple Dialog", options); } }
Focus Trap
Dialog uses the FocusTrap-Component to keep the keyboard-focus within. By default, the first element is focused With DefaultFocus
you can change the behaviour to, for example, focus the last element.
@inject IDialogService DialogService <MudButton @onclick="OpenDialogAsync" Variant="Variant.Filled" Color="Color.Primary"> Open Dialog </MudButton>
@code { private Task OpenDialogAsync() { var options = new DialogOptions { CloseOnEscapeKey = true }; return DialogService.ShowAsync<DialogFocusExample_Dialog>("Last element focused", options); } }
Custom Styling
Classes can be applied to the title, content, and action button sections, or the dialog itself, to make customization easier.
@inject IDialogService DialogService <MudButton @onclick="OpenDialogAsync" Variant="Variant.Filled" Color="Color.Primary"> Open Custom Styled Dialog </MudButton>
@code { private Task OpenDialogAsync() { var options = new DialogOptions { CloseOnEscapeKey = true, CloseButton = true }; return DialogService.ShowAsync<DialogStylingExample_Dialog>("Styling Example Dialog", options); } }