Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 17 additions & 22 deletions src/Maui/Prism.Maui/Dialogs/DialogContainerPage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,12 @@ public virtual async Task DoPop(Page currentPage)
/// <returns>The content layout for the dialog container page.</returns>
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,
Expand Down Expand Up @@ -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;
}

Expand All @@ -146,29 +152,18 @@ 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);

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)
{
Expand Down
23 changes: 21 additions & 2 deletions src/Maui/Prism.Maui/Dialogs/DialogService.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Prism.Common;
using Prism.Navigation;

#nullable enable
namespace Prism.Dialogs;
Expand All @@ -9,18 +10,36 @@ namespace Prism.Dialogs;
public sealed class DialogService : DialogServiceBase
{
private readonly IPageAccessor _pageAccessor;
private readonly IWindowManager _windowManager;

/// <summary>
/// Creates a new instance of the <see cref="DialogService"/> for Maui Applications
/// </summary>
/// <param name="pageAccessor">The <see cref="IPageAccessor"/> used to determine where in the Navigation Stack we need to process the Dialog.</param>
/// <param name="windowManager">The <see cref="IWindowManager"/> used to resolve the current page when the scoped page is no longer attached.</param>
/// <exception cref="ArgumentNullException">Throws when any constructor arguments are null.</exception>
public DialogService(IPageAccessor pageAccessor)
public DialogService(IPageAccessor pageAccessor, IWindowManager windowManager)
{
ArgumentNullException.ThrowIfNull(pageAccessor);
ArgumentNullException.ThrowIfNull(windowManager);
_pageAccessor = pageAccessor;
_windowManager = windowManager;
}

/// <inheritdoc/>
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;
}
}
19 changes: 15 additions & 4 deletions src/Maui/Prism.Maui/Dialogs/DialogServiceBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<IActiveAware>(currentPage, aa => aa.IsActive = false);
MvvmHelpers.InvokeViewAndViewModelAction<IActiveAware>(view, aa => aa.IsActive = true);
PageNavigationService.NavigationSource = PageNavigationSource.Device;
MvvmHelpers.InvokeViewAndViewModelAction<IActiveAware>(currentPage, aa => aa.IsActive = false);
MvvmHelpers.InvokeViewAndViewModelAction<IActiveAware>(view, aa => aa.IsActive = true);
}, TaskScheduler.FromCurrentSynchronizationContext());
}
catch (Exception ex)
{
Expand Down
2 changes: 1 addition & 1 deletion src/Maui/Prism.Maui/Navigation/PrismWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ protected override void OnActivated()
protected override void OnDeactivated()
{
IsActive = false;
MvvmHelpers.InvokeViewAndViewModelAction<IActiveAware>(CurrentPage, x => x.IsActive = true);
MvvmHelpers.InvokeViewAndViewModelAction<IActiveAware>(CurrentPage, x => x.IsActive = false);
}

/// <summary>
Expand Down
Loading