Skip to content

[automated] Merge branch 'main' => 'net11.0'#27

Open
github-actions[bot] wants to merge 977 commits into
net11.0from
merge/main-to-net11.0
Open

[automated] Merge branch 'main' => 'net11.0'#27
github-actions[bot] wants to merge 977 commits into
net11.0from
merge/main-to-net11.0

Conversation

@github-actions

Copy link
Copy Markdown

I detected changes in the main branch which have not been merged yet to net11.0. I'm a robot and am configured to help you automatically keep net11.0 up to date, so I've opened this PR.

This PR merges commits made on main by the following committers:

  • PureWeen
  • github-actions[bot]
  • sbomer
  • TamilarasanSF4853
  • kubaflo
  • Ahamed-Ali
  • JanKrivanek
  • mattleibow
  • Copilot
  • CathyZhu0110
  • Vignesh-SF3580
  • StephaneDelcroix
  • Oxymoron290
  • mmitche
  • akoeplinger
  • sheiksyedm
  • rmarinho
  • pictos
  • lewing
  • jfversluis
  • devanathan-vaithiyanathan
  • noiseonwires
  • jpd21122012
  • rolfbjarne
  • jonathanpeppers
  • dartasen
  • LogishaSelvarajSF4525
  • NafeelaNazhir
  • simonrozsival
  • praveenkumarkarunanithi
  • dotnet-maestro[bot]
  • NirmalKumarYuvaraj
  • dotnet-bot
  • davidortinau
  • SubhikshaSf4851
  • csigs
  • HarishKumarSF4517
  • albyrock87

Instructions for merging from UI

This PR will not be auto-merged. When pull request checks pass, complete this PR by creating a merge commit, not a squash or rebase commit.

merge button instructions

If this repo does not allow creating merge commits from the GitHub UI, use command line instructions.

Instructions for merging via command line

Run these commands to merge this pull request from the command line.

git fetch
git checkout main
git pull --ff-only
git checkout net11.0
git pull --ff-only
git merge --no-ff main

# If there are merge conflicts, resolve them and then run git merge --continue to complete the merge
# Pushing the changes to the PR branch will re-trigger PR validation.
git push https://github.com/PureWeen/maui HEAD:merge/main-to-net11.0
or if you are using SSH
git push git@github.com:PureWeen/maui HEAD:merge/main-to-net11.0

After PR checks are complete push the branch

git push

Instructions for resolving conflicts

⚠️ If there are merge conflicts, you will need to resolve them manually before merging. You can do this using GitHub or using the command line.

Instructions for updating this pull request

Contributors to this repo have permission update this pull request by pushing to the branch 'merge/main-to-net11.0'. This can be done to resolve conflicts or make other changes to this pull request before it is merged.
The provided examples assume that the remote is named 'origin'. If you have a different remote name, please replace 'origin' with the name of your remote.

git fetch
git checkout -b merge/main-to-net11.0 origin/net11.0
git pull https://github.com/PureWeen/maui merge/main-to-net11.0
(make changes)
git commit -m "Updated PR with my changes"
git push https://github.com/PureWeen/maui HEAD:merge/main-to-net11.0
or if you are using SSH
git fetch
git checkout -b merge/main-to-net11.0 origin/net11.0
git pull git@github.com:PureWeen/maui merge/main-to-net11.0
(make changes)
git commit -m "Updated PR with my changes"
git push git@github.com:PureWeen/maui HEAD:merge/main-to-net11.0

Contact .NET Core Engineering (dotnet/dnceng) if you have questions or issues.
Also, if this PR was generated incorrectly, help us fix it. See https://github.com/dotnet/arcade/blob/main/.github/workflows/scripts/inter-branch-merge.ps1.

HarishwaranVijayakumar and others added 30 commits April 4, 2026 14:27
<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!





This pull request introduces a new Material3-based handler for the
`Entry` control on Android, providing improved support for Material
Design features and behaviors. The changes ensure that when Material3 is
enabled, the new handler (`EntryHandler2`) and its associated platform
controls are used instead of the legacy handler. Additional mapping and
platform interop improvements are included to support the new
functionality.

**Material3 Entry Handler Integration:**

* Added a new internal `EntryHandler2` class for Android that wraps the
Material Design `TextInputLayout` and `TextInputEditText`, implementing
property and command mapping for all `Entry` features, including
password toggle, clear button, selection, and text updates.
(`src/Core/src/Handlers/Entry/EntryHandler2.Android.cs`)
* Introduced new internal platform controls `MauiMaterialEditText` and
`MauiMaterialTextInputLayout` to extend Material Design widgets with
Maui-specific behaviors and measurement logic.
(`src/Core/src/Platform/Android/Material3Controls/MauiMaterialEditText.cs`)

**Placeholder Behavior (Material Design Floating Label):**

* When Entry has no Placeholder: The text field displays as an empty
outlined box with no label. When focused, only the outline color changes
to indicate focus state - there is no floating label animation since no
hint text is set.
* When Entry is empty and unfocused (with Placeholder): The placeholder
text appears in an expanded state inside the text field as inline hint
text
* When Entry is focused or contains text (with Placeholder): The
placeholder collapses and animates to a floating label position above
the input field
* This follows the standard Material Design 3 text field guidelines
where the hint transitions between inline placeholder and floating label
states


**Conditional Handler Registration and Mapping:**

* Updated handler registration to use `EntryHandler2` when Material3 is
enabled on Android, falling back to the legacy handler otherwise.
(`src/Controls/src/Core/Hosting/AppHostBuilderExtensions.cs`)
* Added conditional mapping logic for `EntryHandler2`, ensuring correct
property mapping for text and text transform when Material3 is enabled.
(`src/Controls/src/Core/Entry/Entry.Mapper.cs`)
* Provided an overload for `MapText` to support the new Material3
handler with platform-aware data flow direction.
(`src/Controls/src/Core/Entry/Entry.Android.cs`)

**Platform Interop Improvements:**

* Enhanced semantic element retrieval to correctly handle Material3
`TextInputLayout` and `TextInputEditText` controls for accessibility and
automation.
(`src/Core/AndroidNative/maui/src/main/java/com/microsoft/maui/PlatformInterop.java`)
[[1]](diffhunk://#diff-e789f281c1d9f6bc83e7c2c907266663faa42e2130cadb22031efc056b8449feR138-R142)
[[2]](diffhunk://#diff-e789f281c1d9f6bc83e7c2c907266663faa42e2130cadb22031efc056b8449feR55-R56)<!--
!!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING
MAIN. !!!!!!!
-->

### Issues Fixed

<!-- Please make sure that there is a bug logged for the issue being
fixed. The bug should describe the problem and how to reproduce it. -->

Fixes dotnet#33672

### Known issue
   - Placeholder FlowDirection not working
   - Placeholder CharacterSpacing not working  
   - Placeholder HorizontalTextAlignment not working

### Output

| Material 2 | Material 3 |
|----------|----------|
| <video
src="https://github.com/user-attachments/assets/b038cc62-ac97-4961-ae0c-e88a774aefec">
| <video
src="https://github.com/user-attachments/assets/3b1c1977-175b-497a-8846-8f5a47f3994a">
|






<!--
Are you targeting main? All PRs should target the main branch unless
otherwise noted.
-->

---------

Co-authored-by: Sheik Syed <sheiksyedm@syncfusion.com>
<!--
!!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING
MAIN. !!!!!!!
-->

### Description of Change

This pull request makes a minor accessibility change to the
`SliderExtensions.cs` file. The method for updating the thumb image
source on a slider is now public, allowing external code to call it
directly.

* Changed the `UpdateThumbImageSourceAsync` method from `internal` to
`public` in `SliderExtensions.cs`, making it accessible outside the
assembly.

<!--
Are you targeting main? All PRs should target the main branch unless
otherwise noted.
-->
dotnet#34454)

### Description of Change

The fix makes SelfSizing return `NaN` for explicitly-set dimensions
during the arrange pass, so `layout_item` preserves the correct value
from `WidthRequest`/`HeightRequest` instead of overwriting it. When no
explicit size is set (`NaN`), the existing `DesiredSize` behavior is
preserved.

### Issues Fixed

During the arrange pass, FlexLayout's SelfSizing callback
unconditionally returned `child.DesiredSize`, which could be stale when
`WidthRequest`/`HeightRequest` changed dynamically between measure and
arrange passes. The Flex engine's `layout_item` function would then
overwrite the correct explicit Width (from
`EnsureFlexItemPropertiesUpdated`) with the stale `DesiredSize` value.

On Android, arrange-only passes can occur without a preceding measure
(e.g., during scrolling or when `requestLayoutIfNeeded` defers the
layout request), making this timing gap visible. iOS is unaffected
because its layout system couples measure+arrange more tightly via
`InvalidateAncestorsMeasures`.

Fixes dotnet#31109

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…s instead of Enum types (dotnet#34446)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

<!--
!!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING
MAIN. !!!!!!!
-->

### Issue Details
The SourceGen XAML inflator incorrectly generated code referencing
`MyEnumExtension` (the static class) instead of `MyEnum`, causing build
errors:
- `MAUIG1001`: An error occurred while parsing Xaml: Member not found
- `CS0718`: `MyEnumExtension`: static types cannot be used as type
arguments
- `CS0716`: Cannot convert to static type `MyEnumExtension`

### Root Cause
In `TryResolveTypeSymbol()` (`XmlTypeExtensions.cs`) and
`GetTypeReferences()` (`XmlTypeXamlExtensions.cs`), the type resolver
tries the `[Name]Extension` suffix **first** as a convenience for XAML
markup extensions. When a static utility class named `MyEnumExtension`
exists in the same namespace as `MyEnum`, it was returned before ever
trying the exact name `MyEnum`.

### Description of Change
When the Extension-suffix lookup finds a **static type**, skip it and
continue to the exact name. Static types cannot implement
`IMarkupExtension` (static types can't implement interfaces in C#), so
they can never be valid XAML markup extension classes. This is a
minimal, targeted fix that does not affect existing markup extension
resolution (e.g., `{Binding}` → `BindingExtension`, `{x:Type}` →
`TypeExtension`).

Validated the behavior in the following platforms
 
- [x] Android
- [x] Windows
- [x] iOS
- [x] Mac
 
 
### Issues Fixed
  
Fixes dotnet#34021 

### Output  ScreenShot

Android

|Before|After|
|--|--|
| <video
src="https://github.com/user-attachments/assets/d98540c0-1921-4f47-985a-40d118b84469"
>| <video
src="https://github.com/user-attachments/assets/59718a20-506b-4605-8cae-d40427b4d265">|
… text measurements (dotnet#30133)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

<!--
!!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING
MAIN. !!!!!!!
-->

### Issue Detail
When drawing text and its bounding rectangle in GraphicsView using
canvas.GetStringSize(string), the measured size is insufficient, causing
the text to overflow the rectangle.

### Root Cause

String size was calculated inaccurately on iOS and Windows, causing text
to overflow the measured rectangle in GraphicsView.

### Description of Change

iOS: Replaced NSString.GetBoundingRect with
CTFramesetter.SuggestFrameSize, which provides a more accurate and
layout-aware measurement of the text using CoreText. This results proper
frame size of string text.
 
Windows: Replaced the previous bounding logic with CanvasTextLayout from
Win2D to accurately measure text size. Word wrapping is disabled, and
proper horizontal and vertical alignments are applied. The size is taken
from LayoutBounds, with a fallback to DrawBounds to ensure the full text
is enclosed.

### Validated the behaviour in the following platforms
- [x] Android
- [x] Windows
- [x] iOS
- [x] Mac

### Issues Fixed:

Fixes dotnet#18679 

### Screenshots

| Before  | After |
|---------|--------|
|  <img
src="https://github.com/user-attachments/assets/9e882d7e-943e-4201-a002-28e69a0c78f0">
|  <img
src="https://github.com/user-attachments/assets/80d0a81c-ed65-4122-8692-f9ac11e1a796"> 
|
…icatorTemplate (dotnet#31469)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

### Issue Details

- When using IndicatorView with a custom IndicatorTemplate, the
MaximumVisible property is not respected.

### Root Cause
- When IndicatorView uses a custom IndicatorTemplate, the BindableLayout
path is used to render indicators. In
IndicatorStackLayout.BindIndicatorItems(), the full ItemsSource was
passed directly to BindableLayout.SetItemsSource() without applying the
MaximumVisible limit.
- The MaximumVisible cap was only enforced in the native (non-template)
code path.

### Description of Change
- Modified BindIndicatorItems() in IndicatorStackLayout to call a new
GetFilteredItemsSource() helper before binding. The helper returns a
filtered List<object> capped at MaximumVisible items when the source has
more items than the limit; otherwise, it returns the original
ItemsSource unchanged.
- This fix applies on both initial render and when MaximumVisible
changes dynamically, because
IndicatorView.MaximumVisibleProperty.propertyChanged calls
ResetIndicators() → BindIndicatorItems().

### Key Technical Details
**IndicatorStackLayout.GetFilteredItemsSource():**

1. Returns null if ItemsSource is null or MaximumVisible <= 0
2. Returns the original ItemsSource if totalCount <= MaximumVisible (no
filtering needed)
3. Otherwise enumerates up to MaximumVisible items into a new list of
objects and returns it.

**Code path (with IndicatorTemplate):**
BindIndicatorItems() → GetFilteredItemsSource() →
BindableLayout.SetItemsSource(filtered)



**Code path (without IndicatorTemplate):**
Not affected — native rendering handles MaximumVisible separately.

### Issues Fixed
Fixes dotnet#31145 

### Validated the behaviour in the following platforms

- [x] Windows
- [x] Android
- [x] iOS
- [x] Mac

### Output
| Platform | Before Fix | After Fix |
|----------|----------|----------|
| Android | <video
src="https://github.com/user-attachments/assets/b077642e-d634-42a3-8d61-8374ac599b43">
| <video
src="https://github.com/user-attachments/assets/cd4b29b1-4087-41cc-a7f3-67396accfe6b">
|
| iOS | <video
src="https://github.com/user-attachments/assets/297cfde8-bffe-4fcb-a08b-a43362c944ff">
| <video
src="https://github.com/user-attachments/assets/8062d14e-ba38-4015-83dd-ca01e218ebfd">
|
| Windows | <video
src="https://github.com/user-attachments/assets/69aad00d-1f51-47fc-b92f-a8b4fe2741ac">
| <video
src="https://github.com/user-attachments/assets/73eacf53-7d6d-4e87-a606-558ba3482158">
|
| Mac | <video
src="https://github.com/user-attachments/assets/49720bbc-ce67-49d6-95a0-6a8018b5d4fa">
| <video
src="https://github.com/user-attachments/assets/8e494e0c-c795-4b62-894a-ddfdc4e4c27b">
|
…32794)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

### Issue Details

- On iOS and MacCatalyst, when IsEnabled is set to false on
CarouselView, users can still swipe through items. This is inconsistent
with Windows and Android, where IsEnabled = false correctly blocks all
user interactions.

### Root Cause
**iOS** 

- UICollectionView (the native control backing CarouselView) doesn't
inherit from UIControl and doesn't automatically disable user
interaction when IsEnabled is set to false. Unlike other iOS controls,
UICollectionView requires explicitly setting the UserInteractionEnabled
property to false to block touch events.


### Description of Change

- **iOS**: Added MapIsEnabled mapping for the IsEnabled property in
CarouselView handlers (CarouselViewHandler and CarouselViewHandler2) and
implemented the UpdateIsEnabled extension for UICollectionView, which
sets UserInteractionEnabled based on the view's enabled state.


### Issues Fixed
Fixes dotnet#32791 

### Validated the behaviour in the following platforms

- [ ] Windows
- [ ] Android
- [x] iOS
- [x] Mac

### Output
| Before | After |
|----------|----------|
| <video
src="https://github.com/user-attachments/assets/b56ae35f-875e-4918-93b5-011e0e742fba">
| <video
src="https://github.com/user-attachments/assets/5df2b681-9ff0-43dd-a39c-3e3c5cc03f40">
|
…id (dotnet#33469)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

### Issue Details:

Shell TitleView disappears when switching between tabs on Android
(regression from MAUI 9.0.30).
        
### Root Cause:

When switching tabs, we reuses fragments by hiding/showing them if the
ShellNavigationSource is ShellSectionChanged in ShellItemRendererBase
class(line number 235 to 242). When a fragment becomes visible again,
the TitleView handler update isn't automatically triggered, leaving the
TitleView invisible.

### Description of Change:

Updated TitleView of the shellToobar when fragment becomes visible after
being hidden, ensuring TitleView appears when switching back to a tab.

**Tested the behavior in the following platforms.**

- [x] Android
- [x] Windows
- [x] iOS
- [x] Mac

### Reference:

N/A

### Issues Fixed:

Fixes  dotnet#33304  

### Screenshots
| Before  | After  |
|---------|--------|
| <Video
src="https://github.com/user-attachments/assets/ba231765-87bd-4de1-aa4f-86a0bb8de6c2"
Width="300" Height="600"> | <Video
src="https://github.com/user-attachments/assets/621e490d-ab66-4c8a-9d77-43dbd32efd93"
Width="300" Height="600"> |

---------

Co-authored-by: Jakub Florkowski <42434498+kubaflo@users.noreply.github.com>
…lor to platform default (dotnet#33962)

<!--
!!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING
MAIN. !!!!!!!
-->
<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!
### Root cause

- Android used a hard-coded white default in the compatibility Shell
renderer when `ForegroundColor` was cleared.
- Apple Shell navigation bar tint was not restored to the cached
platform default when `ForegroundColor` became `null`.
### Description of change

- Android now resolves Shell's default foreground color from the current
theme instead of always using white.
- Apple now resets `UINavigationBar.TintColor back` to the cached
default when `Shell.ForegroundColor` is cleared.
- Added UI regression coverage for Issue
dotnet#33909 plus new screenshot
baselines.

### Important note if kept as implemented

`ShellRenderer.DefaultForegroundColor` changed from a public field to a
public getter. That is a shipped API change and should be called out
explicitly if intentional.
<!-- Enter description of the fix in this section -->

### Issues Fixed

<!-- Please make sure that there is a bug logged for the issue being
fixed. The bug should describe the problem and how to reproduce it. -->

Fixes dotnet#33909 

### Tested the behavior in the following platforms

- [x] Windows
- [x] Android
- [x] iOS
- [ ] Mac

| Before Issue Android Fix | After Issue Android Fix |
|----------|----------|
| <video
src="https://github.com/user-attachments/assets/f3ad53a3-e9e8-4fb5-8e1b-54589a21e47b">
| <video
src="https://github.com/user-attachments/assets/a6e73c84-cbf0-44f2-add1-83a8e650fa88">
|
| Before Issue iOS Fix | After Issue iOS Fix |
| <video
src="https://github.com/user-attachments/assets/af71bfe2-1036-410e-90d8-6719415f3ca4">
| <video
src="https://github.com/user-attachments/assets/73fab156-0cc7-4c80-bb95-f5f38e0f6324">
|

<!--
Are you targeting main? All PRs should target the main branch unless
otherwise noted.
-->

---
Co-authored-by: Jakub Florkowski <42434498+kubaflo@users.noreply.github.com>
)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!


<!--
!!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING
MAIN. !!!!!!!
-->

### Issue Details
On Android, SwipeItem icons using FontImageSource ignore the Size
property entirely. Icons always render at containerHeight / 2 (~50dp in
a 100dp SwipeView), regardless of the specified FontImageSource.Size.

### Root Cause
GetIconSize() in SwipeItemMenuItemHandler.Android.cs calculates icon
size purely from container dimensions (Math.Min(contentHeight,
contentWidth) / 2). The FontImageSource.Size property is never
consulted. The drawable's intrinsic dimensions are only used for aspect
ratio, not final size.

### Description of Change
When the image source is IFontImageSource, the fix retrieves the font
size via IFontManager.GetFontSize() and converts to pixels using
TypedValue.ApplyDimension() (respecting both screen density and
accessibility text scaling). The result is capped at maxIconSize
(container / 2). Non-font image sources are unchanged.

Validated the behavior in the following platforms
 
- [x] Android
- [ ] Windows
- [x] iOS
- [x] Mac
 
### Issues Fixed
  
Fixes dotnet#34210   

### Output  ScreenShot

| Before  | After  |
|---------|--------|
| <img width="356" height="672" alt="34210-BeforeFix"
src="https://github.com/user-attachments/assets/3b99d126-d936-41e6-8b6a-10ee5b2f0f20"
/> | <img width="356" height="672" alt="34210-After"
src="https://github.com/user-attachments/assets/8d0c9665-588c-403b-b388-54e534e01c31"
/> |
…d during initial loading (dotnet#32789)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

<!--
!!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING
MAIN. !!!!!!!
-->

### Root Cause of the Issue:

- The NavigationViewControl ButtonHolderGrid color was not properly
updated at initial loading. At initial loading the ButtonHolderGrid is
null due to this the color was not updated properly.
 

### Description of Change

- The color is now updated after ApplyTemplate has completed. This
ensures that ButtonHolderGrid is no longer null, and the color is now
applied correctly during initialization.

### Screenshot

| Before Fix | After Fix |
|----------|----------|
| <img
src="https://github.com/user-attachments/assets/001094ea-0357-4a3c-a7a2-db483d1f5c62">
| <img
src="https://github.com/user-attachments/assets/24e402d9-a6e9-4daf-9fe7-89ef32742158">
|
| <video
src="https://github.com/user-attachments/assets/ca102609-2beb-42e9-9403-d885b4adbf4a">
| <video
src="https://github.com/user-attachments/assets/14cd768d-0795-48a6-a120-222d3951b26d">
|



### Issues Fixed


Fixes dotnet#25081
…disable scrolling (dotnet#32516)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

<!--
!!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING
MAIN. !!!!!!!
-->
### Issue Details

- When Shell.FlyoutVerticalScrollMode is set to "Disabled", the flyout
items should not allow vertical scrolling. However, on Windows, the
flyout still scrolls even when the mode is set to "Disabled".

### Root Cause of the issue

- Although UpdateValue(nameof(Shell.FlyoutVerticalScrollMode)) is called
in the OnPaneOpening event, the MapFlyoutVerticalScrollMode method is
never executed because the property is not registered in the
PropertyMapper, which prevents the scroll mode from being disabled.

### Description of Change

- Added mapping for the Shell.FlyoutVerticalScrollMode property in the
handler property map to enable platform-specific updates.
- Ensured that the flyout vertical scroll mode is updated when the Shell
is loaded on Windows by calling
UpdateValue(nameof(Shell.FlyoutVerticalScrollMode)) in OnLoaded.



<!-- Enter description of the fix in this section -->

### Issues Fixed

<!-- Please make sure that there is a bug logged for the issue being
fixed. The bug should describe the problem and how to reproduce it. -->

Fixes dotnet#32416 

### Tested the behaviour in the following platforms

- [x] - Window 
- [ ] - Android
- [x] - iOS
- [x] - Mac

### Output

| Before | After |
|----------|----------|
| <video
src="https://github.com/user-attachments/assets/6a406c6a-8efe-46fc-9e7a-432c836d689d">
| <video
src="https://github.com/user-attachments/assets/1a59f24f-cd50-4f94-8981-640eb52bc009">
|

<!--
Are you targeting main? All PRs should target the main branch unless
otherwise noted.
-->
dotnet#33908)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

### Root Cause
Android:
CollectionView uses `RecyclerView` which implements `IMauiRecyclerView`.
When individual item views within the ItemTemplate have explicit
SafeAreaEdges settings (e.g., `<Grid SafeAreaEdges="Container,None">`),
these item views were excluded from receiving window inset listeners
because of the `|| view is IMauiRecyclerView` check in
`FindListenerForView()`. This prevented per-item safe area control
within CollectionView items.

iOS:
CollectionView uses `UICollectionView`, which inherits from
`UIScrollView`. The `RespondsToSafeArea()` check excluded all
`UIScrollView` descendants, preventing CollectionView cell content views
from responding to safe area. Additionally, cell content views never
receive `SafeAreaInsetsDidChange()` notifications during orientation
changes, causing their `SafeAreaInsets` property to remain **stale**.

### Description of Change

Android:
Removed the `|| parent is IMauiRecyclerView` exclusion from
`FindListenerForView()`. RecyclerView child views (CollectionView item
views) can now receive window inset listeners, enabling `SafeAreaEdges`
on individual item templates.

iOS:
Added an exception in `RespondsToSafeArea()` so that `UICollectionView`
descendants respond to safe area even though they inherit from
`UIScrollView`. For CollectionView descendants, `Window.SafeAreaInsets`
is used instead of `this.SafeAreaInsets` to obtain current safe area
values during layout. In `CrossPlatformArrange()`, safe area
revalidation is forced when window insets change (such as during
orientation changes), ensuring CollectionView cell content views update
correctly.

### Issues Fixed

Fixes dotnet#33604 

### Platforms Tested

- [x] iOS
- [x] Android  
- [x] Windows
- [x] Mac

**Note:** Test scoped to iOS only — Android CI devices lack notch/cutout
hardware, so SafeArea screenshot differences are not observable on that
platform.

### iOS Screenshots
| Before Fix | After Fix |
|------------|-----------|
| <video width="350" alt="withoutfix"
src="https://github.com/user-attachments/assets/466ca15c-db77-45ff-8cfb-2d2042ca3b2d"
/> | <video width="350" alt="withfix"
src="https://github.com/user-attachments/assets/33f9ea89-a8bd-40c8-b4d8-cb0e7d93348c"
/> |

### Android Screenshots
| Before Fix | After Fix |
|------------|-----------|
| <video width="350" alt="withoutfix"
src="https://github.com/user-attachments/assets/df310e84-67a7-42cd-adc0-7f91af1a1d36"
/> | <video width="350" alt="withfix"
src="https://github.com/user-attachments/assets/70c4d21c-5ccc-4492-9bcb-9ee03d6a25c7"
/> |
…dotnet#33632)

> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

This PR enhances the CollectionView Scrolling Feature Matrix by adding
comprehensive support for scroll-related behaviors and events, along
with corresponding UI options and automated test coverage.

The update enables better validation of scrolling scenarios across
grouped and ungrouped CollectionViews, including index-based and
item-based scrolling.

### Issues Identified:

- dotnet#33333
- dotnet#33614

---------
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

This pull request updates the UI for the
`CollectionViewDynamicOptionsPage` by moving the "Apply" action from the
toolbar to a button within the page content. This change improves
discoverability and accessibility of the "Apply" action in CI.

UI changes:

* Removed the ToolbarItem for the "Apply" action from the page's toolbar
and replaced it with a Button labelled "Apply", placed inside the main
content area to address the ValidateDynamicGroupHeaderTemplateDisplayed
test case failure in CI.
…emit errors (dotnet#34078)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!


### Issue Details:

SourceGen does not raise build errors for invalid x:DataType or
bindings,
        
### Root Cause:

The condition uses && (AND), which means BOTH conditions must be true to
report the error:
 
   1. TryResolveTypeSymbol returns false (type resolution failed) AND
   2. symbol is not null
 
This is logically contradictory! When TryResolveTypeSymbol returns
false, the
symbol is typically set to null. So both conditions are almost never
true
  simultaneously, and errors were never reported.

### Description of Change:

Now the error is reported when EITHER condition is true:
 
   1. TryResolveTypeSymbol returns false (type not found) OR
   2. symbol is null (type resolution returned null)
 
  This catches all cases where the type cannot be resolved.

**Tested the behavior in the following platforms.**

- [x] Android
- [x] Windows
- [x] iOS
- [x] Mac

### Reference:

N/A

### Issues Fixed:

Fixes  dotnet#33417     

### Screenshots
| Before  | After  |
|---------|--------|
| <img
src="https://github.com/user-attachments/assets/69f0768a-372b-4a13-b79d-58353040ea05"
Width="300" Height="600"> | <img
src="https://github.com/user-attachments/assets/7a278196-3726-4865-a2c0-4dee01e20eab"
Width="300" Height="600"> |
…teSelector switches templates (dotnet#34534)

> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

### Issue Details
CollectionView retains stale item handlers when content is no longer
active—both when a DataTemplateSelector switches templates and when
items are removed from the backing collection.

###  Root Cause
**Android**

`TemplatedItemViewHolder` removed the logical child during recycle, but
it did not disconnect handlers before releasing the old templated
content.

**Windows**

Windows also showed stale templated item reuse around template changes,
where old templated content and handlers can survive longer than
expected across cleanup and reuse.

### Description of Change
**Android**

- Added `DisconnectHandlers()` to `ItemContentView.Recycle()`
- Updated `TemplatedItemViewHolder.Recycle()` to call
`_itemContentView.Recycle()`
- Cleared `View` and `_selectedTemplate` so recycled items rebuild
cleanly on the next bind

**Windows**

- Updated `ItemsViewHandler.Windows.CleanUpCollectionViewSource()` to
disconnect handlers before removing the logical child
- Kept the Windows fix scoped to the cleanup path

**Scenario 1: DataTemplateSelector switching templates**
When a DataTemplateSelector switches an item from one template to
another, the old templated content is properly disconnected before being
released. This prevents stale handlers from remaining attached to
controls from the previous template.

**Scenario 2: Removing items from CollectionView**
When items are removed from the CollectionView (e.g., using RemoveAt(),
Remove(), or Clear()), the item content is properly cleaned up and its
handlers are disconnected before the view is released. This prevents
stale handlers and avoids the memory leak described in the issue.

### Issues Fixed

Fixes dotnet#32243

### Technical Details

On Android, the important part is using `DisconnectHandlers()` so the
full templated hierarchy is disconnected during recycle, not just the
root view.
On Windows, the selected fix is the cleanup-path handler-disconnect
change in `ItemsViewHandler.Windows.cs`.

### Screenshots

**Android**
| Before Issue Fix | After Issue Fix |
|----------|----------|
| <video width="300" height="600"
src="https://github.com/user-attachments/assets/b4d4ce80-3630-4d27-8fd2-7527862eaed9">
| <video width="300" height="600"
src="https://github.com/user-attachments/assets/5a7652f5-3dda-41e0-a27f-ce4114236c98">
|

**Windows**
| Before Issue Fix | After Issue Fix |
|----------|----------|
| <video width="300" height="600"
src="https://github.com/user-attachments/assets/28586ab0-566b-4e2a-97a6-45f33200d51e">
| <video width="300" height="600"
src="https://github.com/user-attachments/assets/2df1c9fc-ab73-4765-99d3-2a76d500c3ed">
|
…ws compared to other platforms. (dotnet#34112)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!
<!--
!!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING
MAIN. !!!!!!!
-->
### Issue Details

- PanGestureRecognizer, SwipeGestureRecognizer, and
PinchGestureRecognizer exhibit different behavior on Windows compared to
other platforms. On macOS, iOS, and Android, when overlapping views
contain these gesture recognizers, only the topmost (child) view’s
recognizer is invoked, whereas on Windows both parent and child
recognizers are invoked simultaneously.

### Root Cause of the issue

- On Windows, ManipulationDelta is a bubbling routed event that fires on
the child first and then travels to the parent; since HandlePan,
HandleSwipe, and HandlePinch were not setting e.Handled = true, both the
child's and parent's gesture recognizers fired — unlike OnTap, which
already marks the event as handled in ProcessGestureRecognizers

### Description of Change
Gesture handling improvements:

* Updated `HandleSwipe`, `HandlePan`, and `HandlePinch` methods in
`GesturePlatformManager.Windows.cs` to mark gesture events as handled
(`e.Handled = true`), preventing parent gesture recognizers from firing
when a child view's recognizer is triggered.

Testing enhancements:

* Added a new sample page `Issue24252.cs` to demonstrate and manually
verify that only the child gesture recognizer fires when interacting
with the child view for pan, swipe, and pinch gestures.
* Introduced a UI test in `Issue24252.cs` (shared tests) to
automatically validate that only the child gesture recognizer fires for
each gesture type, with assertions for each scenario.

<!-- Enter description of the fix in this section -->

### Issues Fixed

<!-- Please make sure that there is a bug logged for the issue being
fixed. The bug should describe the problem and how to reproduce it. -->

Fixes dotnet#24252 

### Tested the behaviour in the following platforms

- [x] - Windows 
- [x] - Android
- [x] - iOS
- [x] - Mac

| Before | After |
|----------|----------|
| <video
src="https://github.com/user-attachments/assets/e8e76aa3-61e1-4a6e-b3c5-e45fa176d647">
| <video
src="https://github.com/user-attachments/assets/1498621d-d115-4e00-afc8-1f38995404c1">
|



<!--
Are you targeting main? All PRs should target the main branch unless
otherwise noted.
-->
…dotnet#33600)

### Issue Details
When an Entry control has IsPassword="True" on Windows, screen readers
such as Windows Narrator announce the actual characters being typed (for
example, “s”, “w”, “d”) instead of announcing “hidden” or “dot”.


### Root Cause
On Windows, password entries use MauiPasswordTextBox, which inherits
from TextBox and manually obfuscates the password. Screen readers
interact with the control through Windows UI Automation, and because no
accessibility metadata indicates that the control is a password field,
they treat it as a normal text box. As a result, text changes are
announced as typed characters, since the screen reader is never informed
that the control represents a password field.


### Description of Change
Implement a AutomationPeer and override IsPasswordCore() to return true
when the control is in password mode. This ensures screen readers
correctly identify the control as a password field and announce input
appropriately.

**Regarding test case:** This scenario requires manual verification
using a screen reader on Windows, and an automated test cannot be added
for this behavior.

### Issues Fixed

Fixes dotnet#33577

### Screenshots

| Before Issue Fix | After Issue Fix |
|----------|----------|
| <video width="300" height="600"
src="https://github.com/user-attachments/assets/02d81db3-1ccc-4842-a4c3-bac3883e4743">
| <video width="300" height="600"
src="https://github.com/user-attachments/assets/cece814b-8315-4e68-8d6a-38c3abcc5b7b">)
|

---------

Co-authored-by: Jakub Florkowski <42434498+kubaflo@users.noreply.github.com>
…TitleView in a Flyout menu on Windows (dotnet#32800)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

<!--
!!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING
MAIN. !!!!!!!
-->

### Root Cause:

The issue occurs when navigating between pages that reuse the
same NavigationPage instances in a FlyoutPage. When the
same TitleView is applied to a page for the second time, its platform
view still retains the parent–child relationship from the first time it
was displayed. Windows WinUI strictly enforces that an element can have
only one parent, so attempting to assign the same platform view again
without properly clearing its previous parent relationship causes
the “Element is already the child of another element” error.

### Fix Description:

The fix involves calling DisconnectHandler() on the TitleView's handler
before calling ToPlatform(). This triggers RemoveContainer(), which
removes the platform view from its previous parent container, setting
the FrameworkElement.Parentproperty to null. The platform view can then
be safely added to the new toolbar container without conflicts. This
ensures the cleanup happens correctly at the platform level before the
view is reattached.

### Issues Fixed
Fixes dotnet#21037

### Tested the behaviour in the following platforms
- [x] Android
- [x] Windows
- [x] iOS
- [x] Mac

### Output Screenshot
Before Issue Fix | After Issue Fix |
|----------|----------|
|<video width="100" height="100" alt="Before Fix"
src="https://github.com/user-attachments/assets/04191d2d-4ef8-4f77-92a3-405bf2952fad">|<video
width="100" height="100" alt="After Fix"
src="https://github.com/user-attachments/assets/c756923b-f2fe-413a-94e6-069160f5314b">|
…reshView and FlyoutPage (dotnet#34323)

> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

### Description of Change

This PR enhances the event handling support for multiple MAUI controls
by adding comprehensive implementation and validation for
control-specific events, along with corresponding test coverage.

The update includes the addition of events for **Stepper, FlyoutPage,
and RefreshView** controls, ensuring proper event triggering and
argument handling across different platforms.

**Existing Issue Identified**

- dotnet#8296
…et#34033)

<!--
!!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING
MAIN. !!!!!!!
-->
<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!
### Root Cause: 
On Windows, changing the image AspectFill was triggering updates before
the native PlatformView was fully loaded, causing a lifecycle timing
issue that resulted in a COMException when accessing the underlying
WinUI image control.
### Description of Change
* Updated `MapAspect` in `ImageHandler.Windows.cs` to guard against a
null PlatformView and to defer the
`UpdateValue(nameof(IViewHandler.ContainerView))` call until the native
view is loaded.
* This ensures that aspect updates and container view updates occur at
the correct time, preventing issues related to view initialization
order.

**Test Coverage Adjustments:**

* Removed the `#if TEST_FAILS_ON_WINDOWS` preprocessor directive from
`ImageFeatureTests.cs`, re-enabling tests for verifying image aspect
with image sources from files and fonts on Windows. This change ensures
these tests are now executed across all platforms, improving test
coverage.
[[1]](diffhunk://#diff-3d57768a056b285677055acfcae3d41477bc031a79021973db7d30bd4b20e30cL114)
[[2]](diffhunk://#diff-3d57768a056b285677055acfcae3d41477bc031a79021973db7d30bd4b20e30cL179)
<!-- Enter description of the fix in this section -->

### Issues Fixed

<!-- Please make sure that there is a bug logged for the issue being
fixed. The bug should describe the problem and how to reproduce it. -->

Fixes dotnet#29812 

### Tested the behavior in the following platforms

- [x] Windows
- [x] Android
- [x] iOS
- [x] Mac

| Before Issue Fix | After Issue Fix |
|----------|----------|
| <video
src="https://github.com/user-attachments/assets/75976ef5-f4f6-4ef6-8e0b-202eb01dd837">
| <video
src="https://github.com/user-attachments/assets/4dc993c2-57d6-45d4-bf17-bb2ee2a41ed1">
|

<!--
Are you targeting main? All PRs should target the main branch unless
otherwise noted.
-->
…ewHandler2 causing SnapPoints freeze (dotnet#34493)

> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

### Issue details
Selecting SnapPointsType or SnapPointsAlignment from a Picker bound to a
CollectionView on macOS/MacCatalyst causes an ~20-second UI freeze. The
delay increases with each subsequent Picker selection and can eventually
make the app unresponsive.

### Root Cause
SubscribeToItemsLayoutPropertyChanged() in CollectionViewHandler2.iOS.cs
registered a new anonymous lambda on itemsLayout.PropertyChanged each
time SelectLayout() was called. Since SelectLayout() is triggered from
UpdateLayout(), the lambda (which also calls UpdateLayout() on snap
property changes) created an exponential feedback loop:
snap change → lambda fires → UpdateLayout() → SelectLayout() → registers
new lambda
→ all N lambdas fire → N × UpdateLayout() → N new lambdas registered

After 4–5 Picker selections, this resulted in 16+ concurrent layout
rebuilds per change, freezing the UI thread (~4,700 ms measured).
 
### Description of Change
Removed SubscribeToItemsLayoutPropertyChanged() from SelectLayout() and
introduced UpdateItemsLayoutSubscription(), called from MapItemsLayout.
This ensures the subscription updates only when
CollectionView.ItemsLayout is reassigned, not during every layout
update.

### Why Tests were not added:

**Regarding the test case:** On macOS, the Picker opens a native
system-level dropdown that runs outside the app process. Because of
this, it cannot be controlled or captured by Appium or other automated
test frameworks, which results in a timeout when selecting items.
Therefore, the test is ignored here. For more details, see
[dotnet#28024](dotnet#28024).

### Issues Fixed

Fixes dotnet#34419

**Key changes to `CollectionViewHandler2.iOS.cs`:**
- Added `_subscribedItemsLayout` tracking field — guards against
duplicate subscriptions
- Added named `OnItemsLayoutPropertyChanged` handler — can be properly
unsubscribed
- Added `UpdateItemsLayoutSubscription(IItemsLayout)` method —
subscribes once per layout instance
- Called `UpdateItemsLayoutSubscription` from `MapItemsLayout` — correct
lifecycle, not from `SelectLayout`
- Added `DisconnectHandler` override — unsubscribes and cleans up on
handler disconnect to prevent memory leaks

### Technical Details

- **Scope**: iOS and MacCatalyst only (`Handlers/Items2/` — CV2
handler). Android and Windows are unaffected (CV1 reads snap settings at
scroll time).
- **Memory improvement**: Also fixes an event handler leak when
`CollectionView.ItemsLayout` is replaced at runtime.

### Screenshots
**Mac:**
| Before Issue Fix | After Issue Fix |
|----------|----------|
| <video width="300" height="600"
src="https://github.com/user-attachments/assets/b405c277-0662-4166-aed9-7cdd4faffa54">
| <video width="300" height="600"
src="https://github.com/user-attachments/assets/48cf0bb9-322f-472e-9070-43a736d9d2c4">
|

**iOS:**
| Before Issue Fix | After Issue Fix |
|----------|----------|
| <video width="300" height="600"
src="https://github.com/user-attachments/assets/a8c0f35e-d142-486e-a0c7-72dd24e43746">
| <video width="300" height="600"
src="https://github.com/user-attachments/assets/014a65fa-cc62-44e3-9d36-c931581e1f66">
|

---------

Co-authored-by: Jakub Florkowski <42434498+kubaflo@users.noreply.github.com>
…h Programmatically (dotnet#33066)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

### Root cause

The issue occurs because of the order of operations when window
dimensions are changed programmatically versus manually. The
FrameChanged() method determines whether to fire the SizeChanged event
by comparing current property values against incoming frame values.
During manual resize operations, the platform invokes FrameChanged()
first, which then updates the Width and Height properties, successfully
detecting the change and firing the event.
 
However, during programmatic resize, the Width and Height properties
update immediately upon assignment. When the platform subsequently
invokes FrameChanged(), the property values already match the incoming
frame values, causing the comparison to fail and preventing the
SizeChanged event from firing. This breaks AdaptiveTrigger
functionality, which depends on the SizeChanged event to update visual
states.

### Description of Issue Fix

The fix involves adding propertyChanged callbacks to WidthProperty and
HeightProperty that fire the SizeChanged event immediately when
properties change from user code. The existing _batchFrameUpdate flag
distinguishes between user-initiated changes (flag equals zero) and
platform-initiated changes (flag greater than zero), preventing
duplicate event firing. When user code sets Width or Height
programmatically, the callback fires SizeChanged directly.
 
When the platform updates properties through FrameChanged(), the
callback is suppressed and the existing event logic handles
notification. This ensures AdaptiveTrigger receives notifications for
both programmatic and manual resizes without duplicates, following the
established pattern used by ColumnDefinition and RowDefinition in MAUI's
Grid layout system.

Tested the behavior in the following platforms.
 
- [x] Windows
- [x] Mac
- [ ] iOS
- [ ] Android

### Issues Fixed

<!-- Please make sure that there is a bug logged for the issue being
fixed. The bug should describe the problem and how to reproduce it. -->

Fixes dotnet#27646

<!--
Are you targeting main? All PRs should target the main branch unless
otherwise noted.
-->

### Output

| Before Issue Fix | After Issue Fix |
|----------|----------|
| <video width="270" height="600"
src="https://github.com/user-attachments/assets/ec51b57d-09b0-4275-ac82-ee8f512baad3">
| <video width="270" height="600"
src="https://github.com/user-attachments/assets/0259d3e6-4154-4a2a-92cb-91448d846f0c">
|
…target position (dotnet#27300)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

### Issue Details:

When calling ScrollToAsync with the same Y value on a ScrollView that is
already at the target position, the scrolling operation does not
complete on iOS, Windows, and Catalyst platforms. This behavior is
inconsistent with Android, where the scrolling operation completes as
expected.

### Root Cause:

ScrollToAsync hangs when called with the same position the scroll view
is already at. On iOS, UIScrollView.SetContentOffset does not trigger
ScrollAnimationEnded when the content offset doesn't actually change, so
ScrollFinished() is never called and the Task never completes. On
Windows, ScrollViewer.ChangeView has the same behavior when already at
the target offset.

### Description of Change:

iOS (ScrollViewHandler.iOS.cs):
Before calling SetContentOffset, check whether the clamped target
position already matches the current ContentOffset. If already at the
target:

Skip the SetContentOffset call (no-op scroll)
Call ScrollFinished() directly to complete the pending Task
ScrollFinished) handles all other cases unchanged.

Windows (ScrollViewHandler.Windows.cs):
Before calling ChangeView, check whether the clamped target position
already matches the current VerticalOffset/HorizontalOffset. If already
at the target, call ScrollFinished() and return early.

Tests (ScrollViewUITests.cs):
Removed three [FailsOn*WhenRunningOnXamarinUITest] attributes from
ScrollToYTwice that were tracking this issue on iOS, Mac, and Windows.

**Platform Affected**

- iOS (.ios.cs covers both iOS and MacCatalyst)
- MacCatalyst (via ScrollViewHandler.iOS.cs)
- Windows

**Tested the behavior in the following platforms.**

- [x] Android
- [x] Windows
- [x] iOS
- [x] Mac


### Reference:

N/A


### Issues Fixed:



Fixes dotnet#27250



### Screenshots

| Before  | After  |
|---------|--------|
| <video
src="https://github.com/user-attachments/assets/5ec192ee-e9ce-4108-816b-9f35776c86aa"
width="320" height="240" controls></video> | <video
src="https://github.com/user-attachments/assets/787e2b28-c040-4f4c-b6ae-695e3db707ba"
width="320" height="240" controls></video> |
…6213)

### Issues Fixed

Fixes dotnet#26158

|Before|After|
|--|--|
|<video
src="https://github.com/user-attachments/assets/a0b6cebe-7fd4-4705-b32e-81cf3fe34ec7"
width="300px"/>|<video
src="https://github.com/user-attachments/assets/d77f61e9-f198-4fab-8c18-fdab000f94ce"
width="300px"/>|

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
### Issues Fixed

Fixes dotnet#20922

```
<ScrollView>
    <Border HeightRequest="200"
            WidthRequest="200"
            AutomationId="Border"
            BackgroundColor="Red">
        <Border.Shadow>
            <Shadow Radius="20"
                    Brush="Gray"
                    Offset="1,50"/>
        </Border.Shadow>
    </Border>
</ScrollView>
```

|Before|After|
|--|--|
|<img
src="https://github.com/user-attachments/assets/2d0e8e59-5b3e-4953-bc96-75658cd7555e"
width="300px"/>|<img
src="https://github.com/user-attachments/assets/3f31a65f-5cdc-4811-bbbe-f008af39f285"
width="300px"/>|

---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…tureRecognizer from being triggered (dotnet#29814)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

### Issue Details

- Disabled Picker view intercepts GestureRecognizer of parent container.

### Root Cause

- The touch event is triggered regardless of whether the picker is
enabled or disabled. As a result, the base class OnTouchEvent is called
and returns true, indicating that the touch event has been handled. This
behavior prevents the parent tap gesture recognizer from being
triggered.


### Description of Change

- Updated the OnTouchEvent method to return false if the Picker is
disabled, ensuring that touch events are not intercepted by the Picker
in this state.

### Reference :

https://github.com/dotnet/maui/blob/9894e0f8c1fb39a2f71a2ad642ff7c83bbe9031e/src/Core/src/Platform/Android/MauiScrollView.cs#L156-L165

### Issues Fixed
Fixes dotnet#22565 

### Validated the behaviour in the following platforms

- [x] Windows
- [x] Android
- [x] iOS
- [x] Mac

### Output
| Before | After |
|----------|----------|
| <video
src="https://github.com/user-attachments/assets/518eadce-55a6-4a42-9238-054de8ab4fb5">
| <video
src="https://github.com/user-attachments/assets/fc06a418-e175-443e-b7aa-632e9c46f12f">
|
…e Style Causes a System.Runtime.InteropServices.COMException. (dotnet#30047)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

### Root Cause of the issue



- The specific view retains a reference to its `existing `handler when
it is dynamically added as content, especially when the view is defined
as a static resource in a style.

- when the same view instance is added to a new parent (without being
fully removed from the old one), cause WinUI throws a `COMException`





### Description of Change



- Before reusing the view, `detach `its old handler if it exists. This
ensures that MAUI disposes of the existing platform-specific native
view, and allows it to be safely recreated and added to the new parent.





### Issues Fixed



Fixes dotnet#29930 

Android & iOS Fix PR : dotnet#29931


### Tested the behaviour in the following platforms



- [x] Android
- [x] Windows
- [x] iOS
- [x] Mac



### Screenshot



| Before Issue Fix | After Issue Fix |
|----------|----------|
| <video
src="https://github.com/user-attachments/assets/25fd7b6b-fb5c-499e-aa79-c11fa78d5e7f">
| <video
src="https://github.com/user-attachments/assets/28d93a5e-3117-45b3-98cd-2f3ecef1dbd5">
|
Reset patterns:
- global.json
- NuGet.config
- eng/Version.Details.xml
- eng/Versions.props
- eng/common/*
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.