Repository: unoplatform/uno
Pull request #20160: fix(ScrollViewer): invalid Extent when hosting TextBlock with Margin
Author: login: Xiaoy312
Created: 2025-05-01T22:19:18Z | Merged: 2025-05-07T12:07:43Z

GitHub Issue (If applicable): closes unoplatform/uno-private#1211

## PR Type
What kind of change does this PR introduce?
- Bugfix

## What is the current behavior?
When a ScrollViewer host a TextBlock with non-zero Margin, its Extent calculation is mess up, includes the margin twice.

## What is the new behavior?
^ no more.

## PR Checklist
Please check if your PR fulfills the following requirements:
- [ ] Docs have been added/updated which fit [documentation template](https://github.com/unoplatform/uno/blob/master/doc/.feature-template.md) (for bug fixes / features)
- [x] [Unit Tests and/or UI Tests](https://github.com/unoplatform/uno/blob/master/doc/articles/uno-development/working-with-the-samples-apps.md) for the changes have been added (for bug fixes / features) (if applicable)
- [x] Validated PR `Screenshots Compare Test Run` results.
- [x] Contains **NO** breaking changes
- [x] Associated with an issue (GitHub or internal) and uses the [automatic close keywords](https://help.github.com/en/github/managing-your-work-on-github/linking-a-pull-request-to-an-issue).
- [x] Commits must be following the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/#summary) specification.

## Other information
ScrollViewer calculates its Extent based a variety of values from the Content it hosts. In simplify terms, it takes its child's Height or ActualHeight or DesiredHeight, and add margin when necessary (when not using DesiredHeight because it is included already). The problem here is that, with the workaround in #2269, the TextBlock overrides its GetActualHeight. and implemented it by returning DesiredHeight. And, the ScrollViewer isn't aware of this, and slaps another Margin on top of the TextBlock.~~ActualHeight~~DesiredHeight.


Diff:
diff --git a/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_ScrollViewer.cs b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_ScrollViewer.cs
index babcc6f6cd01..af392b2bfaf2 100644
--- a/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_ScrollViewer.cs
+++ b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_ScrollViewer.cs
@@ -5,21 +5,24 @@
 using System.Threading.Tasks;
 using FluentAssertions;
 using FluentAssertions.Execution;
+
 using Microsoft.UI.Xaml;
 using Microsoft.UI.Xaml.Controls;
 using Microsoft.UI.Xaml.Controls.Primitives;
 using Microsoft.UI.Xaml.Input;
 using Microsoft.UI.Xaml.Media;
 using Microsoft.UI.Xaml.Shapes;
-using MUXControlsTestApp.Utilities;
-using Uno.Extensions;
-using Uno.UI.RuntimeTests.Helpers;
 using Windows.Foundation;
 using Windows.Foundation.Metadata;
 using Windows.UI;
 using Windows.UI.Input.Preview.Injection;
 using Windows.UI.ViewManagement;
+
+using MUXControlsTestApp.Utilities;
+using Uno.Extensions;
+using Uno.UI.RuntimeTests.Helpers;
 using Uno.UI.Toolkit.Extensions;
+
 using static Private.Infrastructure.TestServices;
 using Disposable = Uno.Disposables.Disposable;
 using ScrollContentPresenter = Microsoft.UI.Xaml.Controls.ScrollContentPresenter;
@@ -1644,5 +1647,37 @@ public async Task When_TouchScrollDownWithInertiaOnNonScrollable_Then_ParentRece
 			Assert.IsTrue(Math.Abs(parentEndOffset - parent.VerticalOffset) < 1);
 		}
 #endif
+
+		[TestMethod]
+		public async Task When_Hosting_TextBlock_With_Margin()
+		{
+			// test built specifically to verify that a SV nesting a TextBlock with Margin
+			// doesnt includes that Margin twice when calculating its Extent.
+
+			ScrollViewer sv;
+			var setup = new Border()
+			{
+				Height = 100,
+				Child = sv = new ScrollViewer
+				{
+					HorizontalAlignment = HorizontalAlignment.Left,
+					VerticalAlignment = VerticalAlignment.Top,
+					Content = new TextBlock
+					{
+						Text = "Hello",
+						Margin = new Thickness(8, 8, 8, 8),
+					},
+				},
+			};
+
+			await UITestHelper.Load(setup);
+
+			// shouldnt happen, sanity check. if it ever did, we have other problem(s), and the entire test is invalid.
+			Assert.IsTrue(sv.ActualHeight < setup.ActualHeight, $"ScrollViewer (ActualHeight={sv.ActualHeight}) should be shorter than its parent (ActualHeight={setup.Height}).");
+
+			// double Margin inclusion would cause the Extent to "overflow" the Viewport, into the Scrollable
+			Assert.AreEqual(sv.ViewportHeight, sv.ExtentHeight, delta: 1.0, "In a free expanding SV, the Viewport should the same as the Extend.");
+			Assert.AreEqual(0, sv.ScrollableHeight, delta: 1.0, "In a free expanding SV, it should never be scrollable.");
+		}
 	}
 }
diff --git a/src/Uno.UI/UI/Xaml/Controls/ScrollViewer/ScrollViewer.cs b/src/Uno.UI/UI/Xaml/Controls/ScrollViewer/ScrollViewer.cs
index 31a318682621..280659da46ab 100644
--- a/src/Uno.UI/UI/Xaml/Controls/ScrollViewer/ScrollViewer.cs
+++ b/src/Uno.UI/UI/Xaml/Controls/ScrollViewer/ScrollViewer.cs
@@ -736,58 +736,44 @@ void UpdateDimensionProperties()
 			}
 			else if (Content is FrameworkElement fe)
 			{
-				double CalculateExtent(double @explicit, double actual, double desired, bool isStretchAlign, double margin)
+				ExtentHeight = CalculateExtent(this, fe, isHorizontal: false);
+				ExtentWidth = CalculateExtent(this, fe, isHorizontal: true);
+
+				static double CalculateExtent(ScrollViewer sv, FrameworkElement fe, bool isHorizontal)
 				{
-					var shouldIncludeMargin = true;
-					var extent = default(double);
+					var margin = isHorizontal ? GetEffectiveMargin(fe.Margin.Left, fe.Margin.Right) : GetEffectiveMargin(fe.Margin.Top, fe.Margin.Bottom);
+					var @explicit = isHorizontal ? fe.Width : fe.Height;
 					if (@explicit.IsFinite())
 					{
-						extent = @explicit;
+						return sv.LayoutRoundIfNeeded(fe, @explicit + margin);
 					}
-					else
+
+					var isStretchAlign = isHorizontal ? fe.HorizontalAlignment == HorizontalAlignment.Stretch : fe.VerticalAlignment == VerticalAlignment.Stretch;
+					var actual = isHorizontal ? fe.ActualWidth : fe.ActualHeight;
+					if (actual > 0 && isStretchAlign &&
+						// Due to #2269, TextBlock ActualSize is implemented via DesiredSize
+						// which includes the Margin already. We just let it flow to the next block
+						// to avoid including margin twice here.
+						fe is not TextBlock
+					)
 					{
-						if (actual > 0 && isStretchAlign)
-						{
-							extent = LayoutRoundIfNeeded(fe, actual);
-						}
-						else
-						{
-							// desired size has margin built-in already.
-							shouldIncludeMargin = false;
-							extent = desired;
-						}
+						return sv.LayoutRoundIfNeeded(fe, actual + margin);
 					}
 
-					return shouldIncludeMargin ? (extent + margin) : extent;
+					// DesiredSize includes the margin already, so we don't need to add it again.
+					var desired = isHorizontal ? fe.DesiredSize.Width : fe.DesiredSize.Height;
+					return sv.LayoutRoundIfNeeded(fe, desired);
 				}
-
-				ExtentHeight = CalculateExtent(
-					fe.Height,
-					fe.ActualHeight,
-					fe.DesiredSize.Height,
-					fe.VerticalAlignment == VerticalAlignment.Stretch,
-#if !__WASM__
-					fe.Margin.Top + fe.Margin.Bottom
-#else
-					// Issue needs to be fixed first for WASM for Bottom Margin missing
-					// Details here: https://github.com/unoplatform/uno/issues/7000
-					fe.Margin.Top
-#endif
-				);
-
-				ExtentWidth = CalculateExtent(
-					fe.Width,
-					fe.ActualWidth,
-					fe.DesiredSize.Width,
-					fe.HorizontalAlignment == HorizontalAlignment.Stretch,
+				static double GetEffectiveMargin(double leadingMargin, double trailingMargin)
+				{
 #if !__WASM__
-					fe.Margin.Left + fe.Margin.Right
+					return leadingMargin + trailingMargin;
 #else
-					// Issue needs to be fixed first for WASM for Right Margin missing
+					// Issue needs to be fixed first for WASM for missing trailing Margin
 					// Details here: https://github.com/unoplatform/uno/issues/7000
-					fe.Margin.Left
+					return leadingMargin;
 #endif
-				);
+				}
 			}
 			else
 			{


Reviews:
user: login: Xiaoy312
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-01T22:40:34Z
user: login: dr1rrb
state: APPROVED
author_association: MEMBER
submitted_at: 2025-05-02T14:33:35Z
user: login: MartinZikmund
state: APPROVED
author_association: MEMBER
submitted_at: 2025-05-05T10:23:09Z

Review comments:
diff_hunk: @@ -736,58 +736,44 @@ void UpdateDimensionProperties()
 			}
 			else if (Content is FrameworkElement fe)
 			{
-				double CalculateExtent(double @explicit, double actual, double desired, bool isStretchAlign, double margin)
+				ExtentHeight = CalculateExtent(this, fe, isHorizontal: false);
+				ExtentWidth = CalculateExtent(this, fe, isHorizontal: true);
+
+				static double CalculateExtent(ScrollViewer sv, FrameworkElement fe, bool isHorizontal)
 				{
-					var shouldIncludeMargin = true;
-					var extent = default(double);
+					var margin = isHorizontal ? GetEffectiveMargin(fe.Margin.Left, fe.Margin.Right) : GetEffectiveMargin(fe.Margin.Top, fe.Margin.Bottom);
+					var @explicit = isHorizontal ? fe.Width : fe.Height;
 					if (@explicit.IsFinite())
 					{
-						extent = @explicit;
+						return @explicit + margin;
 					}
-					else
+
+					var isStretchAlign = isHorizontal ? fe.HorizontalAlignment == HorizontalAlignment.Stretch : fe.VerticalAlignment == VerticalAlignment.Stretch;
+					var actual = isHorizontal ? fe.ActualWidth : fe.ActualHeight;
+					if (actual > 0 && isStretchAlign &&
+						// Due to #2269, TextBlock ActualSize is implemented via DesiredSize
+						// which includes the Margin already. We just let it flow to the next block
+						// to avoid including margin twice here.
+						fe is not TextBlock
path: src/Uno.UI/UI/Xaml/Controls/ScrollViewer/ScrollViewer.cs
user: login: Xiaoy312
body: the real change is just this line, the rest is refactor
created_at: 2025-05-01T22:39:45Z
author_association: CONTRIBUTOR
diff_hunk: @@ -736,58 +736,44 @@ void UpdateDimensionProperties()
 			}
 			else if (Content is FrameworkElement fe)
 			{
-				double CalculateExtent(double @explicit, double actual, double desired, bool isStretchAlign, double margin)
+				ExtentHeight = CalculateExtent(this, fe, isHorizontal: false);
+				ExtentWidth = CalculateExtent(this, fe, isHorizontal: true);
+
+				static double CalculateExtent(ScrollViewer sv, FrameworkElement fe, bool isHorizontal)
path: src/Uno.UI/UI/Xaml/Controls/ScrollViewer/ScrollViewer.cs
user: login: Xiaoy312
body: is it worth tagging the two with aggressive inlining?
created_at: 2025-05-01T22:40:32Z
author_association: CONTRIBUTOR
diff_hunk: @@ -736,58 +736,44 @@ void UpdateDimensionProperties()
 			}
 			else if (Content is FrameworkElement fe)
 			{
-				double CalculateExtent(double @explicit, double actual, double desired, bool isStretchAlign, double margin)
+				ExtentHeight = CalculateExtent(this, fe, isHorizontal: false);
+				ExtentWidth = CalculateExtent(this, fe, isHorizontal: true);
+
+				static double CalculateExtent(ScrollViewer sv, FrameworkElement fe, bool isHorizontal)
path: src/Uno.UI/UI/Xaml/Controls/ScrollViewer/ScrollViewer.cs
user: login: dr1rrb
body: Not sure it's possible with nested functions and my personal preference would be to keep them here close to their usages. It's not a such hot-path (only warm :P) so I think it's fine.
created_at: 2025-05-02T14:31:39Z
author_association: MEMBER

PR comments:
user: login: unodevops
created_at: 2025-05-02T16:14:27Z
body: 🤖 Your WebAssembly Sample App stage site is ready! Visit it here: https://unowasmprstaging.z20.web.core.windows.net/pr-20160/index.html
author_association: CONTRIBUTOR
user: login: unodevops
created_at: 2025-05-02T16:28:12Z
body: 🤖 Your Docs stage site is ready! Visit it here: https://unodocsprstaging.z13.web.core.windows.net/pr-20160/index.html
author_association: CONTRIBUTOR
user: login: unodevops
created_at: 2025-05-02T17:43:16Z
body: ⚠️⚠️ The build [164120](https://dev.azure.com/uno-platform//Uno%20Platform/_build/results?buildId=164120) has failed on Uno.UI - CI.
author_association: CONTRIBUTOR
user: login: Xiaoy312
created_at: 2025-05-05T13:58:16Z
body: fixme:
- [build 164120](https://dev.azure.com/uno-platform/Uno%20Platform/_build/results?buildId=164120&view=results):
  - [x] skia\\*: When_NonRound_Content_Height
    > Assert.AreEqual failed. Expected a difference no greater than <1E-06> between expected value <36.43675994873047> and actual value <36>.
  - [x] [flaky]~~skia\macos: When_TouchMoveMoreThanHalfItem_Then_FlipOneItem~~
    > Assert.AreEqual failed. Expected:<1>. Actual:<0>. 
author_association: CONTRIBUTOR
user: login: unodevops
created_at: 2025-05-06T16:20:07Z
body: 🤖 Your WebAssembly Sample App 2 stage site is ready! Visit it here: https://unowasmprstaging.z20.web.core.windows.net/pr-20160/wasm-skia-net9/index.html
author_association: CONTRIBUTOR
user: login: unodevops
created_at: 2025-05-06T16:27:45Z
body: 🤖 Your Docs stage site is ready! Visit it here: https://unodocsprstaging.z13.web.core.windows.net/pr-20160/docs/index.html
author_association: CONTRIBUTOR
user: login: unodevops
created_at: 2025-05-06T17:37:53Z
body: ⚠️⚠️ The build [164504](https://dev.azure.com/uno-platform//Uno%20Platform/_build/results?buildId=164504) has failed on Uno.UI - CI.
author_association: CONTRIBUTOR
user: login: jeromelaban
created_at: 2025-05-07T11:31:51Z
body: @mergifyio backport release/stable/6.0 
author_association: MEMBER
user: login: mergify[bot]
created_at: 2025-05-07T11:31:54Z
body: > backport release/stable/6.0

#### ✅ Backports have been created

<details>

* [#20224 fix(ScrollViewer): invalid Extent when hosting TextBlock with Margin (backport #20160)](https://github.com/unoplatform/uno/pull/20224) has been created for branch `release/stable/6.0`

</details>


<!---
DO NOT EDIT
-*- Mergify Payload -*-
{"command": "backport release/stable/6.0", "conclusion": "success", "action_is_running": true}
-*- Mergify Payload End -*-
-->
author_association: CONTRIBUTOR
user: login: nventive-devops
created_at: 2025-05-07T12:14:39Z
body: The [build 164504](https://dev.azure.com/uno-platform/Uno%20Platform/_build/results?buildId=164504) found UI Test snapshots differences: `android-28-net8`: **28**, `android-28-net8-Snap`: **29**, `ios`: **6**, `ios-Snap`: **34**, `skia-linux-screenshots`: **64**, `skia-windows-screenshots`: **410**, `wasm`: **56**, `wasm-automated-net9.0-WinUI-Benchmarks-automated`: **1**, `wasm-automated-net9.0-WinUI-Default-automated`: **19**, `wasm-automated-net9.0-WinUI-RuntimeTests-0`: **1**, `wasm-automated-net9.0-WinUI-RuntimeTests-1`: **1**, `wasm-automated-net9.0-WinUI-RuntimeTests-2`: **0**

<details>
<summary>Details</summary>


* `android-28-net8`: **28** changed over 824

  <details>
  <summary>🚨🚨 Comparison Details (first 20) 🚨🚨</summary>

  - `ListView_SelectedItems_SamplesApp_Windows_UI_Xaml_Controls_ListView_ListViewSelectedItems`
  - `NavigateBackAndForthBetweenMenuItemsAndSettings_Fluent_SamplesApp_Samples_Microsoft_UI_Xaml_Controls_NavigationViewTests_FluentStyle_FluentStyle_NavigationViewSample`
  - `Pivot_Non_PivotItem_Items_UITests_Shared_Windows_UI_Xaml_Controls_Pivot_Pivot_CustomContent_Automated`
  - `Pivot_Non_PivotItemChange_Validation_UITests_Shared_Windows_UI_Xaml_Controls_Pivot_Pivot_CustomContent_Automated`
  - `ProgressRing_IsEnabled_Running_UITests_Windows_UI_Xaml_Controls_ProgressRing_WindowsProgressRing_GH1220`
  - `Detereminate_ProgressRing_Validation75_[#FF0000_#008000_#008000_#008000]_Progress-Ring-Value-75`
  - `When_Click_Outside_Dialog_Expect_No_Dismiss_UITests_Shared_MessageDialogTests_MessageDialogTest`
  - `UpDownEnabledTest_UITests_Shared_Microsoft_UI_Xaml_Controls_NumberBoxTests_NumberBoxPage`
  - `When_SingleSelectionWithItemClick_Then_PointersEvents_UITests_Windows_UI_Xaml_Controls_ListView_ListView_Selection_Pointers`
  - `When_SingleSelectionWithoutItemClick_Then_PointersEvents_UITests_Windows_UI_Xaml_Controls_ListView_ListView_Selection_Pointers`
  - `When_Clip_Is_Set_On_Child_Element_original`
  - `When_Clip_Is_Set_On_Child_Element_UITests_Windows_UI_Xaml_UIElementTests_UIElement_Clipping`
  - `When_MultipleSelectionWithoutItemClick_Then_PointersEvents_UITests_Windows_UI_Xaml_Controls_ListView_ListView_Selection_Pointers`
  - `When_Parent_PointerMoved_After_drag_on_non-scrolling_ScrollViewer`
  - `When_Parent_PointerMoved_After_drag_on_ScrollViewer_-_touch`
  - `UpDownTest_UITests_Shared_Microsoft_UI_Xaml_Controls_NumberBoxTests_NumberBoxPage`
  - `ProgressRing_Visibility_Collapsed_UITests_Windows_UI_Xaml_Controls_ProgressRing_WindowsProgressRing_GH1220`
  - `SequentialAnimations_SamplesApp_Windows_UI_Xaml_Media_Animation_SequentialAnimationsPage`
  - `Detereminate_ProgressRing_Validation25_[#FF0000_#008000_#FF0000_#FF0000]_Progress-Ring-Value-25`
  - `When_ExtendedSelectionWithoutItemClick_Then_PointersEvents_UITests_Windows_UI_Xaml_Controls_ListView_ListView_Selection_Pointers`
  </details>

* `android-28-net8-Snap`: **29** changed over 1067

  <details>
  <summary>🚨🚨 Comparison Details (first 20) 🚨🚨</summary>

  - `SwipeControl_MUXControlsTestApp_SwipeControlPage2_MUXControlsTestApp_SwipeControlPage2`
  - `NavigationView_MUXControlsTestApp_NavigationViewCustomThemeResourcesPage_MUXControlsTestApp_NavigationViewCustomThemeResourcesPage`
  - `TeachingTip_UITests_Microsoft_UI_Xaml_Controls_TeachingTipTests_TeachingTipPage_UITests_Microsoft_UI_Xaml_Controls_TeachingTipTests_TeachingTipPage`
  - `NavigationView_MUXControlsTestApp_NavigationViewTopNavPage_MUXControlsTestApp_NavigationViewTopNavPage`
  - `Scrolling_MUXControlsTestApp_ScrollViewDynamicPage_MUXControlsTestApp_ScrollViewDynamicPage`
  - `MUX_NumberBox_UITests_Shared_Microsoft_UI_Xaml_Controls_NumberBoxTests_NumberBoxPage`
  - `Image_UITests_Windows_UI_Xaml_Controls_ImageTests_SvgImageSource_NoSize_UITests_Windows_UI_Xaml_Controls_ImageTests_SvgImageSource_NoSize`
  - `Scrolling_MUXControlsTestApp_ScrollViewWithScrollControllersPage_MUXControlsTestApp_ScrollViewWithScrollControllersPage`
  - `MediaPlayerElement_Mini_player_UITests_Shared_Windows_UI_Xaml_Controls_MediaPlayerElement_MediaPlayerElement_Minimal`
  - `NavigationView_MUXControlsTestApp_NavigationViewRS4Page_MUXControlsTestApp_NavigationViewRS4Page`
  - `Transform_Basics_UITests_Shared_Windows_UI_Xaml_Media_Transform_Basics`
  - `Icons_UITests_Microsoft_UI_Xaml_Controls_ImageIconTests_ImageIconPage_UITests_Microsoft_UI_Xaml_Controls_ImageIconTests_ImageIconPage`
  - `MediaPlayerElement_Sources_UITests_Shared_Windows_UI_Xaml_Controls_MediaPlayerElement_MediaPlayerElement_Sources`
  - `MediaPlayerElement_Using_3gp_UITests_Shared_Windows_UI_Xaml_Controls_MediaPlayerElement_MediaPlayerElement_3gp_Extension`
  - `MediaPlayerElement_Using_mp3_Audio_only_UITests_Shared_Windows_UI_Xaml_Controls_MediaPlayerElement_MediaPlayerElement_Mp3_Extension`
  - `WebView_UITests_Microsoft_UI_Xaml_Controls_WebView2Tests_WebView2_NavigationProperties_UITests_Microsoft_UI_Xaml_Controls_WebView2Tests_WebView2_NavigationProperties`
  - `WebView_UITests_Windows_UI_Xaml_Controls_WebView_WebView_Title_UITests_Windows_UI_Xaml_Controls_WebView_WebView_Title`
  - `WebView_WebView2_JavascriptInvoke_SamplesApp_Microsoft_UI_Xaml_Controls_WebView2Tests_WebView2_JavascriptInvoke`
  - `WebView_UITests_Microsoft_UI_Xaml_Controls_WebView2Tests_WebView2_Basic_UITests_Microsoft_UI_Xaml_Controls_WebView2Tests_WebView2_Basic`
  - `WebView_WebView2_NavigateToUri_SamplesApp_Microsoft_UI_Xaml_Controls_WebView2Tests_WebView2_NavigateToUri`
  </details>

* `ios`: **6** changed over 255

  <details>
  <summary>🚨🚨 Comparison Details (first 20) 🚨🚨</summary>

  - `ScrollViewer_Content_Margin_After-Scrolled`
  - `ScrollViewer_Content_Margin_Before-Scrolled`
  - `ScrollViewer_Content_Margin_UITests_Windows_UI_Xaml_Controls_ScrollViewerTests_ScrollViewer_Content_Margin`
  - `ProgressRing_IsEnabled_Running_UITests_Windows_UI_Xaml_Controls_ProgressRing_WindowsProgressRing_GH1220`
  - `ProgressRing_Visibility_Collapsed_UITests_Windows_UI_Xaml_Controls_ProgressRing_WindowsProgressRing_GH1220`
  - `ListView_ListViewWithHeader_InitializesTest_SamplesApp_Windows_UI_Xaml_Controls_ListView_HorizontalListViewGrouped`
  </details>

* `ios-Snap`: **34** changed over 984

  <details>
  <summary>🚨🚨 Comparison Details (first 20) 🚨🚨</summary>

  - `Brushes_PanelImageBrush_Uno_UI_Samples_UITests_ImageBrushTestControl_PanelImageBrush`
  - `Brushes_ImageBrushWithCompositeTransform_Uno_UI_Samples_UITests_ImageBrushTestControl_ImageBrushWithCompositeTransform`
  - `Brushes_UITests_Windows_UI_Xaml_Media_BrushesTests_RevealBrush_Fallback_UITests_Windows_UI_Xaml_Media_BrushesTests_RevealBrush_Fallback`
  - `Image_UITests_Shared_Windows_UI_Xaml_Controls_ImageTests_Image_Stretch_Algmnt_Inf_Horizontal_UITests_Shared_Windows_UI_Xaml_Controls_ImageTests_Image_Stretch_Algmnt_Inf_Horizontal`
  - `Pickers_UITests_Windows_UI_Xaml_Controls_CalendarView_CalendarView_Theming_UITests_Windows_UI_Xaml_Controls_CalendarView_CalendarView_Theming`
  - `Brushes_UITests_Shared_Windows_UI_Xaml_Media_ImageBrushTests_ImageBrush_SameWithDelay_UITests_Shared_Windows_UI_Xaml_Media_ImageBrushTests_ImageBrush_SameWithDelay`
  - `ColorPicker_WinUIColorPickerPage_UITests_Shared_Microsoft_UI_Xaml_Controls_ColorPickerTests_WinUIColorPickerPage`
  - `Default_SamplesApp_Wasm_Windows_UI_Xaml_Controls_ListView_ListView_IsSelected_SamplesApp_Wasm_Windows_UI_Xaml_Controls_ListView_ListView_IsSelected`
  - `Default_Uno_UI_Samples_Content_UITests_WebView_WebView_AnchorNavigation_Uno_UI_Samples_Content_UITests_WebView_WebView_AnchorNavigation`
  - `WebView_UITests_Windows_UI_Xaml_Controls_WebView_WebView_Title_UITests_Windows_UI_Xaml_Controls_WebView_WebView_Title`
  - `Brushes_EllipsemaskingEllipseGrid_Uno_UI_Samples_UITests_ImageBrushTestControl_EllipsemaskingEllipseGrid`
  - `Brushes_ImageBrushWithScaleTransform_Uno_UI_Samples_UITests_ImageBrushTestControl_ImageBrushWithScaleTransform`
  - `WebView_UITests_Microsoft_UI_Xaml_Controls_WebView2Tests_WebView2_NavigationProperties_UITests_Microsoft_UI_Xaml_Controls_WebView2Tests_WebView2_NavigationProperties`
  - `WebView_UITests_Microsoft_UI_Xaml_Controls_WebView2Tests_WebView2_Title_UITests_Microsoft_UI_Xaml_Controls_WebView2Tests_WebView2_Title`
  - `MediaPlayerElement_Sources_UITests_Shared_Windows_UI_Xaml_Controls_MediaPlayerElement_MediaPlayerElement_Sources`
  - `MediaPlayerElement_Using_3gp_UITests_Shared_Windows_UI_Xaml_Controls_MediaPlayerElement_MediaPlayerElement_3gp_Extension`
  - `Brushes_Uno_UI_Samples_Samples_Shared_Content_UITests_ImageBrushInList_Uno_UI_Samples_Samples_Shared_Content_UITests_ImageBrushInList`
  - `Icons_UITests_Microsoft_UI_Xaml_Controls_ImageIconTests_ImageIconPage_UITests_Microsoft_UI_Xaml_Controls_ImageIconTests_ImageIconPage`
  - `Brushes_ImageBrushLocalAsset_Uno_UI_Samples_UITests_ImageBrushTestControl_ImageBrushLocalAsset`
  - `Image_Uno_UI_Samples_UITests_Image_Image_Stretch_Alignment_Wider_Uno_UI_Samples_UITests_Image_Image_Stretch_Alignment_Wider`
  </details>

* `skia-linux-screenshots`: **64** changed over 2242

  <details>
  <summary>🚨🚨 Comparison Details (first 20) 🚨🚨</summary>

  - `Examples.png`
  - `ExpanderColorValidationPage.png-dark`
  - `ExpanderColorValidationPage.png`
  - `AutoSuggestBox_Icons.png-dark`
  - `ClipboardTests.png-dark`
  - `CalendarView_Theming.png-dark`
  - `ImagesInlineInFlipView.png-dark`
  - `ImagesInlineInFlipView.png`
  - `ImageBrushInList.png-dark`
  - `ImageBrushInList.png`
  - `BitmapIcon_Monochromatic.png-dark`
  - `DoubleImageBrushInList.png-dark`
  - `DoubleImageBrushInList.png`
  - `ButtonClippingTestsControl.png-dark`
  - `Focus_FocusVisual_Properties.png-dark`
  - `Focus_FocusVisual_Properties.png`
  - `Gamepad_CurrentReading.png-dark`
  - `Gamepad_CurrentReading.png`
  - `Gamepad_Enumeration.png-dark`
  - `Buttons.png-dark`
  </details>

* `skia-windows-screenshots`: **410** changed over 2242

  <details>
  <summary>🚨🚨 Comparison Details (first 20) 🚨🚨</summary>

  - `AutoSuggestBox_Description.png`
  - `AutoSuggestBox_SoftKeboard.png-dark`
  - `BorderVersusPanelClipping.png-dark`
  - `BitmapIcon_Sizing.png-dark`
  - `BitmapIcon_Sizing.png`
  - `CalendarDatePicker_Basics.png`
  - `CalendarDatePicker_Description.png-dark`
  - `Clipping4273.png`
  - `Clipping652.png-dark`
  - `CommandBar_Native_Frame.png-dark`
  - `CommandBar_Native_Frame.png`
  - `CommandBar_Native_With_AppBarButton_With_Foreground.png-dark`
  - `CommandBar_Native_With_AppBarButton_With_Foreground.png`
  - `ContentDialog_Dialogs.png-dark`
  - `ContentDialog_Dialogs.png`
  - `FlipView_Buttons.png-dark`
  - `FlipView_Buttons.png`
  - `Flyout_OverlayInputPassThroughElement.png-dark`
  - `Flyout_OverlayInputPassThroughElement.png`
  - `GridViewEmptyGroups.png-dark`
  </details>

* `wasm`: **56** changed over 1051

  <details>
  <summary>🚨🚨 Comparison Details (first 20) 🚨🚨</summary>

  - `SamplesApp.Windows_UI_Xaml_Controls.ListView.ListView_Padding_Unconstrained`
  - `UITests.Microsoft_UI_Xaml_Controls.InfoBadgeTests.InfoBadgePage`
  - `UITests.Windows_UI_Xaml.DragAndDrop.DragDrop_ListView_Custom_States`
  - `UITests.Windows_UI_Xaml.DragAndDrop.DragDrop_TestPage`
  - `UITests.Windows_UI_Xaml_Controls.Repeater.ItemsRepeater_Nested`
  - `UITests.Shared.Windows_UI_Xaml_Controls.MediaPlayerElement.MediaPlayerElement_Minimal`
  - `UITests.Shared.Windows_UI_Xaml_Controls.MediaPlayerElement.MediaPlayerElement_Ogg_Extension`
  - `Uno.UI.Samples.Content.UITests.GridTestsControl.Grid_InsideStackPanel_InsideButton`
  - `SamplesApp.Wasm.Windows_UI_Xaml_Controls.ComboBox.ComboBox_Header`
  - `SamplesApp.Wasm.Windows_UI_Xaml_Controls.ComboBox.ComboBox_IsSelected`
  - `SamplesApp.Windows_UI_Xaml_Controls.ListView.ListViewIncrementalLoading`
  - `SamplesApp.Windows_UI_Xaml_Controls.ListView.UndefinedHeightListView`
  - `UITests.Windows_UI_Xaml_Controls.ListView.ListView_Selection_Events`
  - `SamplesApp.Windows_UI_Xaml_Controls.ListView.ListView_ItemContainerStyleSelector`
  - `UITests.Windows_UI_Xaml_Controls.ImageTests.SvgImageSource_Basic`
  - `UITests.Windows_UI_Xaml_Controls.ImageTests.SvgImageSource_FromMsAppData`
  - `UITests.Windows_UI_Xaml_Controls.ImageTests.SvgImageSource_FromStream`
  - `UITests.Windows_UI_Xaml_Controls.ComboBox.ComboBox_Stretch`
  - `UITests.Windows_UI_Xaml_Controls.CommandBar.BackButtonImage.CommandBar_Frame`
  - `UITests.Windows_UI_Xaml_Controls.ListView.ListViewItem_Click_Focus`
  </details>

* `wasm-automated-net9.0-WinUI-Benchmarks-automated`: **1** changed over 1

  <details>
  <summary>🚨🚨 Comparison Details (first 20) 🚨🚨</summary>

  - `RunBenchmarks_Benchmarks_Shared_Controls_BenchmarkDotNetTestsPage`
  </details>

* `wasm-automated-net9.0-WinUI-Default-automated`: **19** changed over 875

  <details>
  <summary>🚨🚨 Comparison Details (first 20) 🚨🚨</summary>

  - `Default_StrokeThickness_MyPolygon`
  - `Default_StrokeThickness_MyPolyline`
  - `Default_StrokeThickness_MyEllipse`
  - `When_HollowCircle2_UITests_Windows_UI_Input_PointersTests_HitTest_GeometryGroup`
  - `Default_StrokeThickness_MyPath`
  - `Default_StrokeThickness_MyRect`
  - `When_SingleSelectionWithItemClick_Then_PointersEvents_UITests_Windows_UI_Xaml_Controls_ListView_ListView_Selection_Pointers`
  - `When_SingleSelectionWithoutItemClick_Then_PointersEvents_UITests_Windows_UI_Xaml_Controls_ListView_ListView_Selection_Pointers`
  - `Check_CornerRadius_Border_CornerRadius=5`
  - `Default_StrokeThickness_MyLine`
  - `ListView_SelectedItems_SamplesApp_Windows_UI_Xaml_Controls_ListView_ListViewSelectedItems`
  - `SequentialAnimations_SamplesApp_Windows_UI_Xaml_Media_Animation_SequentialAnimationsPage`
  - `When_ExtendedSelectionWithoutItemClick_Then_PointersEvents_UITests_Windows_UI_Xaml_Controls_ListView_ListView_Selection_Pointers`
  - `When_MultipleSelectionWithoutItemClick_Then_PointersEvents_UITests_Windows_UI_Xaml_Controls_ListView_ListView_Selection_Pointers`
  - `TestProgressRing_InitialState_UITests_Microsoft_UI_Xaml_Controls_ProgressRing_WinUIProgressRing_Features`
  - `When_TransformToVisual_ScrollViewer_UITests_Shared_Windows_UI_Xaml_UIElementTests_TransformToVisual_ScrollViewer`
  - `When_NoSelectionWithItemClick_Then_PointersEvents_UITests_Windows_UI_Xaml_Controls_ListView_ListView_Selection_Pointers`
  - `When_NoSelection_Then_PointersEvents_UITests_Windows_UI_Xaml_Controls_ListView_ListView_Selection_Pointers`
  - `When_Theme_Changed_No_Crash_UITests_Windows_UI_Xaml_Controls_CalendarView_CalendarView_Theming`
  </details>

* `wasm-automated-net9.0-WinUI-RuntimeTests-0`: **1** changed over 1

  <details>
  <summary>🚨🚨 Comparison Details (first 20) 🚨🚨</summary>

  - `RunRuntimeTests_SamplesApp_Samples_UnitTests_UnitTestsPage`
  </details>

* `wasm-automated-net9.0-WinUI-RuntimeTests-1`: **1** changed over 1

  <details>
  <summary>🚨🚨 Comparison Details (first 20) 🚨🚨</summary>

  - `RunRuntimeTests_SamplesApp_Samples_UnitTests_UnitTestsPage`
  </details>

* `wasm-automated-net9.0-WinUI-RuntimeTests-2`: **0** changed over 1

</details>

author_association: CONTRIBUTOR