Displaying a Custom Dialog
Problem
Navigation Extensions currently supports displaying a MessageDialog
. However, MessageDialog
cannot be styled and requires a bit more work to set the text of its actions.
Solution
Setting up a Generic Dialog Model
We can first create our own DialogInfo
object that can hold whatever useful information we want to display:
public partial record DialogInfo
{
public DialogInfo(string title, string content)
{
Title = title;
Content = content;
}
public string Title { get; init; }
public string Content { get; init; }
}
We can then create a generic dialog that will have its own DialogInfo:
public partial record GenericDialogModel(DialogInfo DialogInfo);
We should then create a GenericDialog.xaml file which will take care of the bindings. We will be able to re-use this ContentDialog
throughout the app:
<ContentDialog x:Class="Chefs.Views.GenericDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Chefs.Presentation.Dialogs"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="{Binding DialogInfo.Title}"
Background="{ThemeResource SurfaceBrush}"
CloseButtonText="Close"
Content="{Binding DialogInfo.Content}"
Style="{StaticResource MaterialContentDialogStyle}" />
Using the GenericDialogModel with the Uno Navigation Extension
For the navigation to work, we first have to add a ViewMap
and RouteMap
to our App.xaml.host.cs
file. You can find more information about registering routes here.
public class App : Application
{
...
private static void RegisterRoutes(IViewRegistry views, IRouteRegistry routes)
{
views.Register(
/* other ViewMaps */,
new ViewMap<GenericDialog, GenericDialogModel>(Data: new DataMap<DialogInfo>())
);
routes.Register(
new RouteMap("", View: views.FindByViewModel<ShellModel>(),
Nested: new RouteMap[]
{
/* other RouteMaps */,
new RouteMap("Dialog", View: views.FindByView<GenericDialog>())
}
)
);
}
}
We add our own ShowDialog
method to INavigatorExtensions
:
public static class INavigatorExtensions
{
public static Task<NavigationResponse?> ShowDialog(this INavigator navigator, object sender, DialogInfo dialogInfo, CancellationToken ct)
{
return navigator.NavigateDataAsync(sender, new DialogInfo(dialogInfo.Title, dialogInfo.Content), cancellation: ct);
}
}
We are now ready to show a dialog with custom DialogInfo
wherever we are using navigation. Here's an example where we show the user an error message in our dialog under a condition:
public partial class MyViewModel
{
private readonly INavigator _navigator;
public async ValueTask Submit(CancellationToken ct)
{
if (...)
{
var response = await ...
await _navigator.NavigateBackWithResultAsync(this, data: response);
}
else
{
await _navigator.ShowDialog(this, new DialogInfo("Error", "Please write a cookbook name and select one recipe."), ct);
}
}
}
Source Code
- CreateUpdateCookbookModel code
- Navigation extension method
- App.xaml.host.cs setup (ViewMap)
- App.xaml.host.cs setup (RouteMap)
- GenericDialogModel
- GenericDialog.xaml