diff --git a/src/AddIns/Uno.UI.MediaPlayer.Skia.Gtk/GtkMediaPlayer.cs b/src/AddIns/Uno.UI.MediaPlayer.Skia.Gtk/GtkMediaPlayer.cs
index a1ac28bb61c0..797ce4c76db4 100644
--- a/src/AddIns/Uno.UI.MediaPlayer.Skia.Gtk/GtkMediaPlayer.cs
+++ b/src/AddIns/Uno.UI.MediaPlayer.Skia.Gtk/GtkMediaPlayer.cs
@@ -490,7 +490,7 @@ private void UpdateVideoSizeAllocate(double playerHeight, double playerWidth, ui
protected override Size ArrangeOverride(Size finalSize)
{
- var result = base.ArrangeOverride(finalSize);
+ var result = ArrangeFirstChild(finalSize);
UpdateVideoStretch();
return result;
diff --git a/src/Uno.UI/AssemblyInfo.cs b/src/Uno.UI/AssemblyInfo.cs
index 52dcfc9d40cb..1e1550fb99e2 100644
--- a/src/Uno.UI/AssemblyInfo.cs
+++ b/src/Uno.UI/AssemblyInfo.cs
@@ -26,6 +26,8 @@
[assembly: InternalsVisibleTo("Uno.UI.FluentTheme")]
[assembly: InternalsVisibleTo("Uno.UI.FluentTheme.v1")]
[assembly: InternalsVisibleTo("Uno.UI.FluentTheme.v2")]
+[assembly: InternalsVisibleTo("Uno.UI.MediaPlayer.Skia.Gtk")]
+[assembly: InternalsVisibleTo("Uno.UI.MediaPlayer.WebAssembly")]
[assembly: AssemblyMetadata("IsTrimmable", "True")]
diff --git a/src/Uno.UI/Controls/NativeFramePresenter.iOS.cs b/src/Uno.UI/Controls/NativeFramePresenter.iOS.cs
index 9e7d06489753..926c6063454c 100644
--- a/src/Uno.UI/Controls/NativeFramePresenter.iOS.cs
+++ b/src/Uno.UI/Controls/NativeFramePresenter.iOS.cs
@@ -87,6 +87,12 @@ public NativeFramePresenter()
NavigationController.NavigationBarHidden = true;
}
+ protected override Size MeasureOverride(Size availableSize)
+ => MeasureFirstChild(availableSize);
+
+ protected override Size ArrangeOverride(Size finalSize)
+ => ArrangeFirstChild(finalSize);
+
internal protected override void OnTemplatedParentChanged(DependencyPropertyChangedEventArgs e)
{
base.OnTemplatedParentChanged(e);
diff --git a/src/Uno.UI/Microsoft/UI/Xaml/Controls/MenuBar/NativeMenuBarPresenter.macOS.cs b/src/Uno.UI/Microsoft/UI/Xaml/Controls/MenuBar/NativeMenuBarPresenter.macOS.cs
index 3d0c2c9a8254..eb18a923f282 100644
--- a/src/Uno.UI/Microsoft/UI/Xaml/Controls/MenuBar/NativeMenuBarPresenter.macOS.cs
+++ b/src/Uno.UI/Microsoft/UI/Xaml/Controls/MenuBar/NativeMenuBarPresenter.macOS.cs
@@ -4,6 +4,7 @@
using System.Text;
using AppKit;
using Foundation;
+using Windows.Foundation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
@@ -90,5 +91,11 @@ private void OnItemActivated(MenuFlyoutItem flyoutItem)
{
flyoutItem.InvokeClick();
}
+
+ protected override Size MeasureOverride(Size availableSize)
+ => MeasureFirstChild(availableSize);
+
+ protected override Size ArrangeOverride(Size finalSize)
+ => ArrangeFirstChild(finalSize);
}
}
diff --git a/src/Uno.UI/UI/Xaml/Controls/AnimatedVisualPlayer/AnimatedVisualPlayer.cs b/src/Uno.UI/UI/Xaml/Controls/AnimatedVisualPlayer/AnimatedVisualPlayer.cs
index 331db5570b8c..e4aca5ceaaed 100644
--- a/src/Uno.UI/UI/Xaml/Controls/AnimatedVisualPlayer/AnimatedVisualPlayer.cs
+++ b/src/Uno.UI/UI/Xaml/Controls/AnimatedVisualPlayer/AnimatedVisualPlayer.cs
@@ -132,8 +132,10 @@ protected override Size MeasureOverride(Size availableSize)
}
else
{
- return base.MeasureOverride(availableSize);
+ return MeasureFirstChild(availableSize);
}
}
+
+ protected override Size ArrangeOverride(Size finalSize) => ArrangeFirstChild(finalSize);
}
}
diff --git a/src/Uno.UI/UI/Xaml/Controls/Border/Border.Layout.cs b/src/Uno.UI/UI/Xaml/Controls/Border/Border.Layout.cs
index 0d5aaa876a2e..5883ab094f8c 100644
--- a/src/Uno.UI/UI/Xaml/Controls/Border/Border.Layout.cs
+++ b/src/Uno.UI/UI/Xaml/Controls/Border/Border.Layout.cs
@@ -32,12 +32,19 @@ protected override Size MeasureOverride(Size availableSize)
var padding = Padding;
var borderThickness = BorderThickness;
- var measuredSize = base.MeasureOverride(
- new Size(
+ Size measuredSize;
+ if (Child is { } child)
+ {
+ var childSize = new Size(
availableSize.Width - padding.Left - padding.Right - borderThickness.Left - borderThickness.Right,
availableSize.Height - padding.Top - padding.Bottom - borderThickness.Top - borderThickness.Bottom
- )
- );
+ );
+ measuredSize = MeasureElement(child, childSize);
+ }
+ else
+ {
+ measuredSize = default;
+ }
return new Size(
measuredSize.Width + padding.Left + padding.Right + borderThickness.Left + borderThickness.Right,
diff --git a/src/Uno.UI/UI/Xaml/Controls/ContentPresenter/ContentPresenter.cs b/src/Uno.UI/UI/Xaml/Controls/ContentPresenter/ContentPresenter.cs
index edbe1efc807a..788f6f9e8ad3 100644
--- a/src/Uno.UI/UI/Xaml/Controls/ContentPresenter/ContentPresenter.cs
+++ b/src/Uno.UI/UI/Xaml/Controls/ContentPresenter/ContentPresenter.cs
@@ -1131,7 +1131,7 @@ protected override Size MeasureOverride(Size size)
var padding = Padding;
var borderThickness = BorderThickness;
- var measuredSize = base.MeasureOverride(
+ var measuredSize = MeasureFirstChild(
new Size(
size.Width - padding.Left - padding.Right - borderThickness.Left - borderThickness.Right,
size.Height - padding.Top - padding.Bottom - borderThickness.Top - borderThickness.Bottom
diff --git a/src/Uno.UI/UI/Xaml/Controls/Control/Control.cs b/src/Uno.UI/UI/Xaml/Controls/Control/Control.cs
index fcce5bf91b65..4d2965b00f5e 100644
--- a/src/Uno.UI/UI/Xaml/Controls/Control/Control.cs
+++ b/src/Uno.UI/UI/Xaml/Controls/Control/Control.cs
@@ -466,6 +466,12 @@ private protected override void OnLoaded()
}
+ protected override Size MeasureOverride(Size availableSize)
+ => MeasureFirstChild(availableSize);
+
+ protected override Size ArrangeOverride(Size finalSize)
+ => ArrangeFirstChild(finalSize);
+
///
/// Loads the relevant control template so that its parts can be referenced.
///
diff --git a/src/Uno.UI/UI/Xaml/Controls/Panel/Panel.cs b/src/Uno.UI/UI/Xaml/Controls/Panel/Panel.cs
index 7a2251a847a5..2fe80909754e 100644
--- a/src/Uno.UI/UI/Xaml/Controls/Panel/Panel.cs
+++ b/src/Uno.UI/UI/Xaml/Controls/Panel/Panel.cs
@@ -65,16 +65,6 @@ private protected virtual void OnChildAdded(IFrameworkElement element)
UpdateTransitions(element);
}
- // In WinUI, the base Panel doesn't measure or arrange anything. This is likely due
- // to FrameworkElement.Override itself not doing anything. In Uno,
- // FrameworkElement.Override have a default implementation that assumes
- // a single child and measures/arranges it. This is helpful as most elements have one or no
- // children. However, since derived types of Panel can add their own Children, we need to make
- // sure our internal FrameworkElement.Override isn't used by user-defined
- // subclasses of Panel.
- protected override Size MeasureOverride(Size availableSize) => new Size(0, 0);
- protected override Size ArrangeOverride(Size finalSize) => finalSize;
-
private void UpdateTransitions(IFrameworkElement element)
{
if (_transitionHelper == null)
diff --git a/src/Uno.UI/UI/Xaml/Controls/TextBox/TextBoxView.wasm.cs b/src/Uno.UI/UI/Xaml/Controls/TextBox/TextBoxView.wasm.cs
index 776b1dd89d4e..f526a2e17a6b 100644
--- a/src/Uno.UI/UI/Xaml/Controls/TextBox/TextBoxView.wasm.cs
+++ b/src/Uno.UI/UI/Xaml/Controls/TextBox/TextBoxView.wasm.cs
@@ -115,6 +115,9 @@ internal void Select(int start, int length)
protected override Size MeasureOverride(Size availableSize) => MeasureView(availableSize);
+ protected override Size ArrangeOverride(Size finalSize)
+ => ArrangeFirstChild(finalSize);
+
internal void SetPasswordRevealState(PasswordRevealState revealState)
{
if (IsMultiline)
diff --git a/src/Uno.UI/UI/Xaml/ElementStub.cs b/src/Uno.UI/UI/Xaml/ElementStub.cs
index a636fc0fd3f5..57d9412407e8 100644
--- a/src/Uno.UI/UI/Xaml/ElementStub.cs
+++ b/src/Uno.UI/UI/Xaml/ElementStub.cs
@@ -7,6 +7,7 @@
using Uno.Foundation.Logging;
using Uno.UI;
using Uno.UI.DataBinding;
+using Windows.Foundation;
#if __ANDROID__
using View = Android.Views.View;
@@ -140,6 +141,12 @@ private static void OnLoadChanged(DependencyObject dependencyObject, DependencyP
///
public Func ContentBuilder { get; set; }
+ protected override Size MeasureOverride(Size availableSize)
+ => MeasureFirstChild(availableSize);
+
+ protected override Size ArrangeOverride(Size finalSize)
+ => ArrangeFirstChild(finalSize);
+
protected override void OnVisibilityChanged(Visibility oldValue, Visibility newValue)
{
base.OnVisibilityChanged(oldValue, newValue);
diff --git a/src/Uno.UI/UI/Xaml/FrameworkElement.cs b/src/Uno.UI/UI/Xaml/FrameworkElement.cs
index 5163936ff7e9..3aa385e3e4f1 100644
--- a/src/Uno.UI/UI/Xaml/FrameworkElement.cs
+++ b/src/Uno.UI/UI/Xaml/FrameworkElement.cs
@@ -272,8 +272,7 @@ public bool IsParsing
/// The size that this object determines it needs during layout, based on its calculations of the allocated sizes for child objects or based on other considerations such as a fixed container size.
protected virtual Size MeasureOverride(Size availableSize)
{
- var child = this.FindFirstChild();
- return child != null ? MeasureElement(child, availableSize) : new Size(0, 0);
+ return default;
}
///
@@ -283,21 +282,7 @@ protected virtual Size MeasureOverride(Size availableSize)
/// The actual size that is used after the element is arranged in layout.
protected virtual Size ArrangeOverride(Size finalSize)
{
- var child = this.FindFirstChild();
-
- if (child != null)
- {
-#if UNO_REFERENCE_API
- child.Arrange(new Rect(0, 0, finalSize.Width, finalSize.Height));
-#else
- ArrangeElement(child, new Rect(0, 0, finalSize.Width, finalSize.Height));
-#endif
- return finalSize;
- }
- else
- {
- return finalSize;
- }
+ return finalSize;
}
///
@@ -756,6 +741,23 @@ internal virtual void OnLayoutUpdated()
private protected virtual Thickness GetBorderThickness() => Thickness.Empty;
+ private protected Size MeasureFirstChild(Size availableSize)
+ {
+ var child = this.FindFirstChild();
+ return child != null ? MeasureElement(child, availableSize) : new Size(0, 0);
+ }
+
+ private protected Size ArrangeFirstChild(Size finalSize)
+ {
+ var child = this.FindFirstChild();
+ if (child != null)
+ {
+ ArrangeElement(child, new Rect(0, 0, finalSize.Width, finalSize.Height));
+ }
+
+ return finalSize;
+ }
+
#if XAMARIN
private static FrameworkElement FindPhaseEnabledRoot(ContentControl content)
{