diff --git a/src/Maui/Prism.Maui/Dialogs/DialogContainerPage.cs b/src/Maui/Prism.Maui/Dialogs/DialogContainerPage.cs
index 42f40ab98..ad3cd0de2 100644
--- a/src/Maui/Prism.Maui/Dialogs/DialogContainerPage.cs
+++ b/src/Maui/Prism.Maui/Dialogs/DialogContainerPage.cs
@@ -89,7 +89,12 @@ public virtual async Task DoPop(Page currentPage)
/// The content layout for the dialog container page.
protected virtual View GetContentLayout(Page currentPage, View dialogView, bool hideOnBackgroundTapped, ICommand dismissCommand, IDialogParameters parameters)
{
- var overlay = new AbsoluteLayout();
+ // Use a Grid so the mask fills the page naturally without needing
+ // AbsoluteLayout proportional sizing, which conflicted with the
+ // WidthRequest/HeightRequest bindings and caused tap gestures on
+ // the mask to not fire reliably across MAUI platforms.
+ var overlay = new Grid();
+
var popupContainer = new DialogContainerView
{
IsPopupContent = true,
@@ -118,20 +123,21 @@ protected virtual View GetContentLayout(Page currentPage, View dialogView, bool
source: this));
}
- AbsoluteLayout.SetLayoutFlags(popupContainer, AbsoluteLayoutFlags.PositionProportional);
- var popupBounds = DialogLayout.GetLayoutBounds(dialogView);
- AbsoluteLayout.SetLayoutBounds(popupContainer, popupBounds);
-
- var useMask = DialogLayout.GetUseMask(popupContainer.Content) ?? true;
+ var useMask = DialogLayout.GetUseMask(dialogView) ?? true;
if (useMask)
{
var mask = GetMask(currentPage, dialogView, hideOnBackgroundTapped, dismissCommand);
- AbsoluteLayout.SetLayoutFlags(mask, AbsoluteLayoutFlags.All);
- AbsoluteLayout.SetLayoutBounds(mask, new Rect(0, 0, 1, 1));
overlay.Children.Add(mask);
}
- overlay.Children.Add(popupContainer);
+ // Keep an AbsoluteLayout for the popup so LayoutBounds positioning still works
+ var popupArea = new AbsoluteLayout();
+ AbsoluteLayout.SetLayoutFlags(popupContainer, AbsoluteLayoutFlags.PositionProportional);
+ var popupBounds = DialogLayout.GetLayoutBounds(dialogView);
+ AbsoluteLayout.SetLayoutBounds(popupContainer, popupBounds);
+ popupArea.Children.Add(popupContainer);
+
+ overlay.Children.Add(popupArea);
return overlay;
}
@@ -146,7 +152,6 @@ protected virtual View GetContentLayout(Page currentPage, View dialogView, bool
private View GetMask(Page currentPage, View dialogView, bool hideOnBackgroundTapped, ICommand dismissCommand)
{
View mask = DialogLayout.GetMask(dialogView);
- var reference = currentPage.GetParentWindow().Page;
if (mask is null)
{
Style overlayStyle = GetOverlayStyle(dialogView, currentPage);
@@ -154,21 +159,11 @@ private View GetMask(Page currentPage, View dialogView, bool hideOnBackgroundTap
mask = new BoxView
{
Style = overlayStyle,
- //HeightRequest = reference.Height,
- //WidthRequest = reference.Width
};
}
- mask.SetBinding(WidthRequestProperty, new Binding
- {
- Path = nameof(Width),
- Source = reference
- });
- mask.SetBinding(HeightRequestProperty, new Binding
- {
- Path = nameof(Height),
- Source = reference
- });
+ // No explicit WidthRequest/HeightRequest needed — the Grid parent
+ // sizes the mask to fill the page automatically.
if (hideOnBackgroundTapped)
{
diff --git a/src/Maui/Prism.Maui/Dialogs/DialogService.cs b/src/Maui/Prism.Maui/Dialogs/DialogService.cs
index d36a6d0f4..6d97bd48b 100644
--- a/src/Maui/Prism.Maui/Dialogs/DialogService.cs
+++ b/src/Maui/Prism.Maui/Dialogs/DialogService.cs
@@ -1,4 +1,5 @@
using Prism.Common;
+using Prism.Navigation;
#nullable enable
namespace Prism.Dialogs;
@@ -9,18 +10,36 @@ namespace Prism.Dialogs;
public sealed class DialogService : DialogServiceBase
{
private readonly IPageAccessor _pageAccessor;
+ private readonly IWindowManager _windowManager;
///
/// Creates a new instance of the for Maui Applications
///
/// The used to determine where in the Navigation Stack we need to process the Dialog.
+ /// The used to resolve the current page when the scoped page is no longer attached.
/// Throws when any constructor arguments are null.
- public DialogService(IPageAccessor pageAccessor)
+ public DialogService(IPageAccessor pageAccessor, IWindowManager windowManager)
{
ArgumentNullException.ThrowIfNull(pageAccessor);
+ ArgumentNullException.ThrowIfNull(windowManager);
_pageAccessor = pageAccessor;
+ _windowManager = windowManager;
}
///
- protected override Page? GetCurrentPage() => _pageAccessor.Page;
+ protected override Page? GetCurrentPage()
+ {
+ var page = _pageAccessor.Page;
+
+ // If the scoped page is still connected to a window, use it
+ if (page?.GetParentWindow() is not null)
+ return page;
+
+ // Fallback: the scoped page was detached (e.g. after absolute navigation).
+ // Resolve the current page from the active window instead.
+ if (_windowManager.Current is PrismWindow prismWindow)
+ return prismWindow.CurrentPage;
+
+ return page;
+ }
}
diff --git a/src/Maui/Prism.Maui/Dialogs/DialogServiceBase.cs b/src/Maui/Prism.Maui/Dialogs/DialogServiceBase.cs
index 940520836..dbe81e8a8 100644
--- a/src/Maui/Prism.Maui/Dialogs/DialogServiceBase.cs
+++ b/src/Maui/Prism.Maui/Dialogs/DialogServiceBase.cs
@@ -97,12 +97,23 @@ async Task DialogAware_RequestClose(IDialogResult outResult)
var dismissCommand = new DelegateCommand(() => dialogAware.RequestClose.Invoke(), dialogAware.CanCloseDialog);
+ // ConfigureLayout is async (it awaits DoPush internally). Since ShowDialog is void,
+ // we use ContinueWith to defer post-push work until the modal is actually displayed.
+ // Without this, NavigationSource resets and IsActive updates race ahead of the push.
PageNavigationService.NavigationSource = PageNavigationSource.DialogService;
- dialogModal.ConfigureLayout(currentPage, view, closeOnBackgroundTapped, dismissCommand, parameters);
- PageNavigationService.NavigationSource = PageNavigationSource.Device;
+ dialogModal.ConfigureLayout(currentPage, view, closeOnBackgroundTapped, dismissCommand, parameters)
+ .ContinueWith(t =>
+ {
+ if (t.IsFaulted)
+ {
+ callback.Invoke(t.Exception?.InnerException ?? t.Exception);
+ return;
+ }
- MvvmHelpers.InvokeViewAndViewModelAction(currentPage, aa => aa.IsActive = false);
- MvvmHelpers.InvokeViewAndViewModelAction(view, aa => aa.IsActive = true);
+ PageNavigationService.NavigationSource = PageNavigationSource.Device;
+ MvvmHelpers.InvokeViewAndViewModelAction(currentPage, aa => aa.IsActive = false);
+ MvvmHelpers.InvokeViewAndViewModelAction(view, aa => aa.IsActive = true);
+ }, TaskScheduler.FromCurrentSynchronizationContext());
}
catch (Exception ex)
{
diff --git a/src/Maui/Prism.Maui/Navigation/PrismWindow.cs b/src/Maui/Prism.Maui/Navigation/PrismWindow.cs
index bd0debf92..2ad4dcf2b 100644
--- a/src/Maui/Prism.Maui/Navigation/PrismWindow.cs
+++ b/src/Maui/Prism.Maui/Navigation/PrismWindow.cs
@@ -105,7 +105,7 @@ protected override void OnActivated()
protected override void OnDeactivated()
{
IsActive = false;
- MvvmHelpers.InvokeViewAndViewModelAction(CurrentPage, x => x.IsActive = true);
+ MvvmHelpers.InvokeViewAndViewModelAction(CurrentPage, x => x.IsActive = false);
}
///