diff --git a/src/CommunityToolkit.Maui.Core/Handlers/Popup/PopUpHandler.windows.cs b/src/CommunityToolkit.Maui.Core/Handlers/Popup/PopUpHandler.windows.cs
index f369daf75..0c3e24321 100644
--- a/src/CommunityToolkit.Maui.Core/Handlers/Popup/PopUpHandler.windows.cs
+++ b/src/CommunityToolkit.Maui.Core/Handlers/Popup/PopUpHandler.windows.cs
@@ -1,6 +1,7 @@
using CommunityToolkit.Maui.Core.Views;
using Microsoft.Maui.Handlers;
using Microsoft.Maui.Platform;
+using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
@@ -88,7 +89,7 @@ public static void MapColor(PopupHandler handler, IPopup view)
/// An instance of .
public static void MapSize(PopupHandler handler, IPopup view)
{
- handler.PlatformView.SetSize(view);
+ handler.PlatformView.SetSize(view, handler.MauiContext);
}
///
@@ -100,6 +101,10 @@ protected override void DisconnectHandler(Popup platformView)
parent.IsHitTestVisible = true;
platformView.IsOpen = false;
platformView.Closed -= OnClosed;
+ if (MauiContext is not null)
+ {
+ MauiContext.GetPlatformWindow().SizeChanged -= OnSizeChanged;
+ }
}
///
@@ -114,6 +119,10 @@ protected override void ConnectHandler(Popup platformView)
{
platformView.Closed += OnClosed;
platformView.ConfigureControl(VirtualView, MauiContext);
+ if (MauiContext is not null)
+ {
+ MauiContext.GetPlatformWindow().SizeChanged += OnSizeChanged;
+ }
base.ConnectHandler(platformView);
}
@@ -124,4 +133,13 @@ void OnClosed(object? sender, object e)
VirtualView.Handler?.Invoke(nameof(IPopup.OnDismissedByTappingOutsideOfPopup));
}
}
+
+ void OnSizeChanged(object? sender, WindowSizeChangedEventArgs e)
+ {
+ if (VirtualView is not null)
+ {
+ PopupExtensions.SetSize(PlatformView, VirtualView, MauiContext);
+ PopupExtensions.SetLayout(PlatformView, VirtualView, MauiContext);
+ }
+ }
}
\ No newline at end of file
diff --git a/src/CommunityToolkit.Maui.Core/Views/Popup/PopupExtensions.windows.cs b/src/CommunityToolkit.Maui.Core/Views/Popup/PopupExtensions.windows.cs
index 7a63639d6..cb9cbbbaa 100644
--- a/src/CommunityToolkit.Maui.Core/Views/Popup/PopupExtensions.windows.cs
+++ b/src/CommunityToolkit.Maui.Core/Views/Popup/PopupExtensions.windows.cs
@@ -54,7 +54,7 @@ public static void ConfigureControl(this Popup mauiPopup, IPopup popup, IMauiCon
mauiPopup.Child = handler.VirtualView.Content?.ToPlatform(mauiContext);
}
- mauiPopup.SetSize(popup);
+ mauiPopup.SetSize(popup, mauiContext);
mauiPopup.SetLayout(popup, mauiContext);
}
@@ -63,41 +63,58 @@ public static void ConfigureControl(this Popup mauiPopup, IPopup popup, IMauiCon
///
/// An instance of .
/// An instance of .
- public static void SetSize(this Popup mauiPopup, IPopup popup)
+ /// An instance of .
+ public static void SetSize(this Popup mauiPopup, IPopup popup, IMauiContext? mauiContext)
{
+ ArgumentNullException.ThrowIfNull(mauiContext);
+ ArgumentNullException.ThrowIfNull(popup.Content);
+
const double defaultBorderThickness = 0;
const double defaultSize = 600;
- var standardSize = new Size { Width = defaultSize, Height = defaultSize / 2 };
+ var popupParent = mauiContext.GetPlatformWindow();
+ var currentSize = new Size { Width = defaultSize, Height = defaultSize / 2 };
- var currentSize = popup.Size != default ? popup.Size : standardSize;
-
- if (popup.Content is not null && popup.Size == default)
+ if (popup.Size.IsZero)
{
- var content = popup.Content;
- // There are some situations when the Width and Height values will be NaN
- // normally when the dev doesn't set the HeightRequest and WidthRequest
- // and we can't use comparison on those, so the only to prevent the application to crash
- // is using this try/catch
- try
+ if (double.IsNaN(popup.Content.Width) || (double.IsNaN(popup.Content.Height)))
{
- currentSize = new Size(content.Width, content.Height);
+ currentSize = popup.Content.Measure(popupParent.Bounds.Width, popupParent.Bounds.Height);
+
+ if (double.IsNaN(popup.Content.Width))
+ {
+ currentSize.Width = popup.HorizontalOptions == LayoutAlignment.Fill ? popupParent.Bounds.Width : currentSize.Width;
+ }
+ if (double.IsNaN(popup.Content.Height))
+ {
+ currentSize.Height = popup.VerticalOptions == LayoutAlignment.Fill ? popupParent.Bounds.Height : currentSize.Height;
+ }
}
- catch (ArgumentException)
+ else
{
+ currentSize.Width = popup.Content.Width;
+ currentSize.Height = popup.Content.Height;
}
}
-
- if (popup.Parent is IView popupParent)
+ else
{
- currentSize.Width = Math.Min(currentSize.Width, popupParent.Frame.Width);
- currentSize.Height = Math.Min(currentSize.Height, popupParent.Frame.Height);
+ currentSize.Width = popup.Size.Width;
+ currentSize.Height = popup.Size.Height;
}
+ currentSize.Width = Math.Min(currentSize.Width, popupParent.Bounds.Width);
+ currentSize.Height = Math.Min(currentSize.Height, popupParent.Bounds.Height);
+
mauiPopup.Width = currentSize.Width;
mauiPopup.Height = currentSize.Height;
mauiPopup.MinWidth = mauiPopup.MaxWidth = currentSize.Width + (defaultBorderThickness * 2);
mauiPopup.MinHeight = mauiPopup.MaxHeight = currentSize.Height + (defaultBorderThickness * 2);
+
+ if (mauiPopup.Child is FrameworkElement control)
+ {
+ control.Width = mauiPopup.Width;
+ control.Height = mauiPopup.Height;
+ }
}
///
@@ -109,10 +126,12 @@ public static void SetSize(this Popup mauiPopup, IPopup popup)
public static void SetLayout(this Popup mauiPopup, IPopup popup, IMauiContext? mauiContext)
{
ArgumentNullException.ThrowIfNull(mauiContext);
- var popupParent = popup.Parent as IView;
- popup.Content?.Measure(double.PositiveInfinity, double.PositiveInfinity);
- var contentSize = popup.Content?.ToPlatform(mauiContext).DesiredSize ?? Windows.Foundation.Size.Empty;
- var popupParentFrame = popupParent?.Frame ?? new Rect(0, 0, contentSize.Width, contentSize.Height);
+ ArgumentNullException.ThrowIfNull(popup.Content);
+
+ var popupParent = mauiContext.GetPlatformWindow();
+ popup.Content.Measure(double.PositiveInfinity, double.PositiveInfinity);
+ var contentSize = popup.Content.ToPlatform(mauiContext).DesiredSize;
+ var popupParentFrame = popupParent.Bounds;
var verticalOptions = popup.VerticalOptions;
var horizontalOptions = popup.HorizontalOptions;
@@ -144,19 +163,19 @@ public static void SetLayout(this Popup mauiPopup, IPopup popup, IMauiContext? m
{
mauiPopup.DesiredPlacement = PopupPlacementMode.BottomEdgeAlignedRight;
mauiPopup.HorizontalOffset = (popupParentFrame.Width - contentSize.Width);
- mauiPopup.VerticalOffset = popupParentFrame.Height + contentSize.Height / 2;
+ mauiPopup.VerticalOffset = popupParentFrame.Height - contentSize.Height;
}
else if (IsBottom(verticalOptions, horizontalOptions))
{
mauiPopup.DesiredPlacement = PopupPlacementMode.Bottom;
mauiPopup.HorizontalOffset = (popupParentFrame.Width - contentSize.Width) / 2;
- mauiPopup.VerticalOffset = popupParentFrame.Height + contentSize.Height / 2;
+ mauiPopup.VerticalOffset = popupParentFrame.Height - contentSize.Height;
}
else if (IsBottomLeft(verticalOptions, horizontalOptions))
{
mauiPopup.DesiredPlacement = PopupPlacementMode.BottomEdgeAlignedLeft;
mauiPopup.HorizontalOffset = 0;
- mauiPopup.VerticalOffset = popupParentFrame.Height + contentSize.Height / 2;
+ mauiPopup.VerticalOffset = popupParentFrame.Height - contentSize.Height;
}
else if (IsLeft(verticalOptions, horizontalOptions))
{
@@ -164,6 +183,54 @@ public static void SetLayout(this Popup mauiPopup, IPopup popup, IMauiContext? m
mauiPopup.HorizontalOffset = 0;
mauiPopup.VerticalOffset = (popupParentFrame.Height - contentSize.Height) / 2;
}
+ else if (IsCenter(verticalOptions, horizontalOptions))
+ {
+ mauiPopup.DesiredPlacement = PopupPlacementMode.Auto;
+ mauiPopup.HorizontalOffset = (popupParentFrame.Width - contentSize.Width) / 2;
+ mauiPopup.VerticalOffset = (popupParentFrame.Height - contentSize.Height) / 2;
+ }
+ else if (IsFillLeft(verticalOptions, horizontalOptions))
+ {
+ mauiPopup.DesiredPlacement = PopupPlacementMode.Auto;
+ mauiPopup.HorizontalOffset = 0;
+ mauiPopup.VerticalOffset = (popupParentFrame.Height - contentSize.Height) / 2;
+ }
+ else if (IsFillCenter(verticalOptions, horizontalOptions))
+ {
+ mauiPopup.DesiredPlacement = PopupPlacementMode.Auto;
+ mauiPopup.HorizontalOffset = (popupParentFrame.Width - contentSize.Width) / 2;
+ mauiPopup.VerticalOffset = (popupParentFrame.Height - contentSize.Height) / 2;
+ }
+ else if (IsFillRight(verticalOptions, horizontalOptions))
+ {
+ mauiPopup.DesiredPlacement = PopupPlacementMode.Auto;
+ mauiPopup.HorizontalOffset = (popupParentFrame.Width - contentSize.Width);
+ mauiPopup.VerticalOffset = (popupParentFrame.Height - contentSize.Height) / 2;
+ }
+ else if (IsTopFill(verticalOptions, horizontalOptions))
+ {
+ mauiPopup.DesiredPlacement = PopupPlacementMode.Auto;
+ mauiPopup.HorizontalOffset = (popupParentFrame.Width - contentSize.Width) / 2;
+ mauiPopup.VerticalOffset = 0;
+ }
+ else if (IsCenterFill(verticalOptions, horizontalOptions))
+ {
+ mauiPopup.DesiredPlacement = PopupPlacementMode.Auto;
+ mauiPopup.HorizontalOffset = (popupParentFrame.Width - contentSize.Width) / 2;
+ mauiPopup.VerticalOffset = (popupParentFrame.Height - contentSize.Height) / 2;
+ }
+ else if (IsBottomFill(verticalOptions, horizontalOptions))
+ {
+ mauiPopup.DesiredPlacement = PopupPlacementMode.Auto;
+ mauiPopup.HorizontalOffset = (popupParentFrame.Width - contentSize.Width) / 2;
+ mauiPopup.VerticalOffset = popupParentFrame.Height - contentSize.Height;
+ }
+ else if (IsFill(verticalOptions, horizontalOptions))
+ {
+ mauiPopup.DesiredPlacement = PopupPlacementMode.Auto;
+ mauiPopup.HorizontalOffset = (popupParentFrame.Width - contentSize.Width) / 2;
+ mauiPopup.VerticalOffset = (popupParentFrame.Height - contentSize.Height) / 2;
+ }
else if (popup.Anchor is null)
{
mauiPopup.DesiredPlacement = PopupPlacementMode.Auto;
@@ -183,5 +250,13 @@ public static void SetLayout(this Popup mauiPopup, IPopup popup, IMauiContext? m
static bool IsBottom(LayoutAlignment verticalOptions, LayoutAlignment horizontalOptions) => verticalOptions == LayoutAlignment.End && horizontalOptions == LayoutAlignment.Center;
static bool IsBottomLeft(LayoutAlignment verticalOptions, LayoutAlignment horizontalOptions) => verticalOptions == LayoutAlignment.End && horizontalOptions == LayoutAlignment.Start;
static bool IsLeft(LayoutAlignment verticalOptions, LayoutAlignment horizontalOptions) => verticalOptions == LayoutAlignment.Center && horizontalOptions == LayoutAlignment.Start;
+ static bool IsCenter(LayoutAlignment verticalOptions, LayoutAlignment horizontalOptions) => verticalOptions == LayoutAlignment.Center && horizontalOptions == LayoutAlignment.Center;
+ static bool IsFillLeft(LayoutAlignment verticalOptions, LayoutAlignment horizontalOptions) => verticalOptions == LayoutAlignment.Fill && horizontalOptions == LayoutAlignment.Start;
+ static bool IsFillCenter(LayoutAlignment verticalOptions, LayoutAlignment horizontalOptions) => verticalOptions == LayoutAlignment.Fill && horizontalOptions == LayoutAlignment.Center;
+ static bool IsFillRight(LayoutAlignment verticalOptions, LayoutAlignment horizontalOptions) => verticalOptions == LayoutAlignment.Fill && horizontalOptions == LayoutAlignment.End;
+ static bool IsTopFill(LayoutAlignment verticalOptions, LayoutAlignment horizontalOptions) => verticalOptions == LayoutAlignment.Start && horizontalOptions == LayoutAlignment.Fill;
+ static bool IsCenterFill(LayoutAlignment verticalOptions, LayoutAlignment horizontalOptions) => verticalOptions == LayoutAlignment.Center && horizontalOptions == LayoutAlignment.Fill;
+ static bool IsBottomFill(LayoutAlignment verticalOptions, LayoutAlignment horizontalOptions) => verticalOptions == LayoutAlignment.End && horizontalOptions == LayoutAlignment.Fill;
+ static bool IsFill(LayoutAlignment verticalOptions, LayoutAlignment horizontalOptions) => verticalOptions == LayoutAlignment.Fill && horizontalOptions == LayoutAlignment.Fill;
}
}
\ No newline at end of file